CppSharp
CppSharp copied to clipboard
CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS does not work for "external return decl" ignored on Windows (MSVC)
Brief Description
I had fairly big C++ project to wrap into C#, it works mostly on Linux with dotnet 3.1, but not on Windows https://bitbucket.org/fathomteam/moab/src/master/
Because the target c++ headers do not use __declspec(dllexport)
at all, and there are too much work to add them.
I wonder whether CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS could be a solution, if not why.
Instead of CppSharp user manual's solution
If you're exposing C++ functions on Windows, you'll have to add the __declspec(dllexport) directive, otherwise the symbols won't be found when calling them from the managed world. You could also add the directive to a class directly, like this:
class __declspec(dllexport) ExposedClass
{
// class definition
}
a quick solution by CMake is tried
if(MSVC)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()
Symbols are exported into dll, but got lots of warning, almost half API are not generated. E.g.
CppSharp warning:
Function 'get_coords' was ignored due to external return decl
The target C++ API virtual ErrorCode get_coords( const Range& entity_handles, double* coords ) const;
Actually, the return type enum has been correctly generated as
public enum ErrorCode: uint
on Linux, public enum ErrorCode
on Windows
=== Related CppSharp code
// Generator/Passes/CheckIgnoreDecls.cs
private bool HasInvalidType(Type type, Declaration decl, out string msg)
{
// ... skipped
var module = decl.TranslationUnit.Module;
if (Options.DoAllModulesHaveLibraries() &&
module != Options.SystemModule && ASTUtils.IsTypeExternal(module, type))
{
msg = "external";
return true;
}
}
// ASTUtils.IsTypeExternal
public static bool IsTypeExternal(Module module, Type type)
{
var typeModule = type.GetModule();
return typeModule != null && typeModule.Dependencies.Contains(module);
}
a hack to disable/skip this return type check failed with assertion
if (HasInvalidType(ret.Type, function, out msg) && false) // tmp diasable this
{
function.ExplicitlyIgnore();
Diagnostics.Debug("Function '{0}' was ignored due to {1} return decl type {2}",
function.Name, msg, ret);
return false;
}
Vtable assertion in ClassLayout.cs failed Debug.Assert(Kind == VTableComponentKind.FunctionPointer);
OS: Windows
Used headers
https://bitbucket.org/fathomteam/moab/src/master/src/moab/Core.hpp https://bitbucket.org/fathomteam/moab/src/master/src/moab/Types.hpp
Used settings
Target: MSVC/
Other settings
Stack trace or incompilable generated code
Would you be able to extract just the offending piece of C++ as the header? Makes testing much easier.
Thank you, I may try debug it again.
I just do not understand, what is external type and external return decl.
The different on set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
and __dllspec(export).
My understanding is: On every platform, clang is used to parse c++ headers, libraries files, not per-platform G++/MSVC compilers. So, on Windows, MingW32 ABI is not supported.
I just add __dllspec(export)
to some class header files, it helps, even CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS is still used for MSVC to build DLL
I have modify the CppSharp, monkey patch to bypass some skipping, and generated the API I needed. Generator/Passes/CheckIgnoredDecls.cs
if (HasInvalidType(ret.Type, function, out msg)) // tmp by pass this if_condition does not work
{
if(ret.ToString().Contains("moab.ErrorCode")) // working
return true;
if(ret.ToString().Contains("moab.Range.const_iterator")) // working
return true;
if(ret.ToString().Contains("moab.Range")) // working
return true;
function.ExplicitlyIgnore();
Diagnostics.Debug("Function '{0}' was ignored due to {1} return decl type {2}",
function.Name, msg, ret);
return false;
}
There is other errors, I will open another issue.
Thank you