Closed ktngoykalolo closed 7 years ago
Options.Headers only contains the names of headers, you need to add their containing directory to IncludeDirs. You may use our own bindings as an example: https://github.com/mono/CppSharp/blob/master/src/CppParser/ParserGen/ParserGen.cs#L59 .
Hello @ddobrev ,
I have been able to successfully generate bindings for the library mentioned above.
however I have also used the //driver options to compile code drOptions.CompileCode = true;
but when it is compiling, CppSharp is failing to compile and gives 2 errors :
C:\Users\Kevin\documents\visual studio 2015\Projects\GammuCppSharp\GammuCppSharp.CLI\bin\Debug\GammuSharp\GammuSharp.cs(2519,15) : error CS0208: Impossible de prendre l'adresse, d'obtenir la taille ou de déclarer un pointeur vers un type managé ('GSMCodeName')
C:\Users\Kevin\documents\visual studio 2015\Projects\GammuCppSharp\GammuCppSharp.CLI\bin\Debug\GammuSharp\GammuSharp.cs(2529,15) : error CS0208: Impossible de prendre l'adresse, d'obtenir la taille ou de déclarer un pointeur vers un type managé ('GSMCodeName')
C:\Users\Kevin\documents\visual studio 2015\Projects\GammuCppSharp\GammuCppSharp.CLI\bin\Debug\GammuSharp\GammuSharp.cs(17677,37) : error CS0111: Le type 'corecrt_search' définit déjà un membre appelé 'Lfind' avec les mêmes types de paramètre
C:\Users\Kevin\documents\visual studio 2015\Projects\GammuCppSharp\GammuCppSharp.CLI\bin\Debug\GammuSharp\GammuSharp.cs(17688,37) : error CS0111: Le type 'corecrt_search' définit déjà un membre appelé 'Lsearch' avec les mêmes types de paramètre
`
any help regarding this ???
Seems like there is some generation bug when wrapping your library. Can you share your source code with us or try to send the minimal source code that reproduces the issue?
using System.IO;
using CppSharp;
using CppSharp.Generators;
using CppSharp.Parser;
using CppSharp.Parser.AST;
namespace GammuCppSharp
{
/// <summary>
/// main generator for Gammu bindings in C#
/// </summary>
class MyGenerator : ILibrary
{
private const string GammuRootPath = @"C:\Program Files\Gammu 1.38.1";
private const string GammuIncludePath = GammuRootPath + @"\include\gammu\";
private const string GammuLibPath = GammuRootPath + @"\lib\";
private const string _theotherPath = @"C:\gammu-1.38.1\libgammu";
private const string _theotherincludepath = @"C:\gammu-1.38.1\include";
public void Setup(Driver driver)
{
PrepareDriver(driver);
}
private void PrepareDriver(Driver driver)
{
//parse options configuration
var myparseOptions = driver.ParserOptions;
//adding include dirs
myparseOptions.AddIncludeDirs(GammuIncludePath);
//myparseOptions.AddIncludeDirs(_theotherincludepath);
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/atlmfc/include");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/um");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/shared");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/winrt");
myparseOptions.AddIncludeDirs(@"C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6/Include/um");
// myparseOptions.AddIncludeDirs(GammuIncludePath);
myparseOptions.AddLibraryDirs(GammuLibPath);
myparseOptions.Abi = CppSharp.Parser.AST.CppAbi.Microsoft;
myparseOptions.LibraryFile = "Gammu.lib";
// myparseOptions.LanguageVersion = LanguageVersion.C;
myparseOptions.SetupIncludes();
myparseOptions.MicrosoftMode = true;
//driveroptions configuration
var drOptions = driver.Options;
drOptions.GeneratorKind = GeneratorKind.CSharp;
drOptions.OutputDir = "GammuSharp";
drOptions.LibraryName = "GammuSharp";
drOptions.Libraries.Add("Gammu.lib");
drOptions.CompileCode = true;
drOptions.MarshalCharAsManagedChar = true;
drOptions.GenerateSupportFiles = true;
//drOptions.DryRun = true;
drOptions.Platform = TargetPlatform.Windows;
drOptions.VsVersion = VisualStudioVersion.Latest;
//drOptions.UseHeaderDirectories = true;
//drOptions.Verbose = true;
drOptions.OutputNamespace = "GammuSharp";
//header files to include
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-wap.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-unicode.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-types.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-statemachine.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-smsd.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-settings.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-security.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-ringtone.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-nokia.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-misc.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-message.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-memory.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-limits.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-keys.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-inifile.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-info.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-file.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-error.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-debug.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-datetime.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-config.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-category.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-callback.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-call.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-calendar.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-bitmap.h");
//myparseOptions.AddSourceFiles(GammuIncludePath + "gammu-backup.h");
drOptions.Headers.Add(GammuIncludePath + "gammu.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-wap.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-unicode.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-types.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-statemachine.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-smsd.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-settings.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-security.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-ringtone.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-nokia.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-misc.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-message.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-memory.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-limits.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-keys.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-inifile.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-info.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-file.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-error.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-debug.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-datetime.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-config.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-category.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-callback.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-call.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-calendar.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-bitmap.h");
drOptions.Headers.Add(GammuIncludePath + "gammu-backup.h");
//driver.Setup();
//driver.ParseCode();
//driver.ParseLibraries();
//driver.ProcessCode();
//driver.CompileCode(drOptions.MainModule);
}
static string GetSourceDirectory(string dir)
{
var directory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (directory != null)
{
var path = Path.Combine(directory.FullName, dir);
if (Directory.Exists(path) &&
Directory.Exists(Path.Combine(directory.FullName, "deps")))
return path;
directory = directory.Parent;
}
throw new Exception("Could not find build directory: " + dir);
}
public void SetupPasses(Driver driver)
{
}
public void Preprocess(Driver driver, CppSharp.AST.ASTContext ctx)
{
//throw new NotImplementedException();
}
public void Postprocess(Driver driver, CppSharp.AST.ASTContext ctx)
{
//throw new NotImplementedException();
}
}
}
could you open this issue ?
@ktngoykalolo if you build C++# from source code, it's relatively easy to debug yourself. Let me know if you'd like to try.
Hey Kevin, can you also paste a gist with generated file GammuSharp.cs
?
it is a really long file. I have zipped the whole package with the generated file in this link on OneDrive
I mostly work from the Nuget Package. I could give it shot. I don't have a deep background on C++ or how compilers are created but why not give it a try? let me try to clone the CppSharp project.
Took a quick look, minimized test case for first failure:
struct GSM_CodeName {};
extern const GSM_CodeName GSM_Countries[];
It might be related to https://github.com/mono/CppSharp/issues/744#issuecomment-275966916.
I am on a tight deadline. what do you suggest I do to circumvent this bug ?
Try commenting the offending declarations in the header files run the generator again.
Negative. impossible to comment those declarations as they have lots of dependencies on them. I did comment them and it made things much more worse. I suspect the issue is with the generated code itself. maybe I could configure a post-process pass to try to resolve this issue. maybe this is a mapping issue, what is your opinion ?
`CS0029 Impossible de convertir implicitement le type 'GammuSharp.GSMCodeName.__Internal' en 'GammuSharp.GSMCodeName*'`
digging deeper into the errors by importing the generated bindings into another blank project
Try this:
public void Postprocess(Driver driver, CppSharp.AST.ASTContext ctx)
{
foreach (var item in ctx.FindDecl<CppSharp.AST.Variable>("GSM_Networks"))
item.GenerationKind = CppSharp.AST.GenerationKind.None;
foreach (var item in ctx.FindDecl<CppSharp.AST.Variable>("GSM_Countries"))
item.GenerationKind = CppSharp.AST.GenerationKind.None;
}
Did it work?
Hello I tried it but it didn't work. From what I understand, the thing is when cppsharp generates the classes for GSM_Networks and GSM_Countries, there is a member where instead of returning internal classes that member returns pointers, which is why it is giving that error message. I managed to clear the other error message by changing myparseOptions.AddIncludeDirs to myparseOptions.AddSystemIncludeDirs
Hello I finally managed to do it!!! I took your processing code and put it in the Preprocess method! it worked !!!! bindings are working successfully !!!
@ktngoykalolo I am really glad to hear it. Still, we are going to fix the real issue as soon as time permits.
sure sure! many thanks for the support and the assist! truly appreciated! the issue can be closed once and for all.
this wrapper is completely raw, I get errors saying that it can only be used in an "unsafe context"
Have you allowed unsafe code in your project settings?
hello, Yes I did. I am digging deeper on that subject. some types have members returning pointers instead of basic value types. I will see if I can have some preprocess passes to fix those mappings.
Perhaps we miss some member to mark as unsafe. Could you please paste an example?
I will put it on pastebin, the code is quite long.
Hello, I just realized that I had to add the "unsafe" keyword to the method I was using, now I no longer have that message. but I still need to investigate those pointers and bytes types. I currently have some connectivity issues, I will try to post the code.
Great to hear that part of the issue isn't related to CppSharp. Please post the code @ktngoykalolo , I'll take a look into them too :wink: !
here is a paste valid for a week : http://pastebin.com/QR4cSb6W
I think I have to study the code in depth to understand its structure. then I can optimize the bindings using preprocess passes and instructions.
what is the easiest way to customize the bindings ? I would like to modify the mappings of some functions with pointers as return type.
@ktngoykalolo if you want to always present that pointer as the same type, use type maps. If you only want to do it for certain functions, you need a custom pass.
@ddobrev , yes you are right, I will need a custom pass where I could specify type mappings for certain functions. is there a particular manner to map constructors ? there is a structure that is being initialized as a pointer by a specific (global) method. I could map that using a special constructor in the wrapping code.
Brief Description
I would like to generate bindings for Gammu, a C library that is freely available. when trying to do so it gives an error saying it does not find the gammu.lib file nor the headers. I suspect I am not putting them at the right place. where should I put the files so that cppsharp sees them ?
OS: Windows here is a sample of my generator
` class MyGenerator : ILibrary {
`