3F / Conari

🧬 One-touch unmanaged memory, runtime dynamic use of the unmanaged native C/C++ in .NET world, related P/Invoke features, and …

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Undecorate functions from C++ compilers

3F opened this issue · comments

the develop branch is already contains DLR features, but it's not possible for exported functions from C++ compiler.

i.e.:

#define LIBAPI_CPP  __declspec(dllexport) // will decorated like: ?getSeven@API@UnLib@Conari@r_eg@net@@YAGXZ
                                          // e.g.: unsigned short net::r_eg::Conari::UnLib::API::getSeven(void)
#define LIBAPI  extern "C" __declspec(dllexport) // will undecorated like from C compiler: getSeven()

thus we can't use this like l->?getSeven@API@UnLib@Conari@r_eg@net@@YAGXZ() even if it's possible, it is... omg :)

Currently, we can also use a standard bind methods, like:

l.bind<Func<ushort>>("?getD_Seven@API@UnLib@Conari@r_eg@net@@YAGXZ")();

// or

l.bind(Dynamic.GetMethodInfo(typeof(ushort)), "?getD_Seven@API@UnLib@Conari@r_eg@net@@YAGXZ")
                 .dynamic
                 .Invoke(null, new object[0]);

but it still not useful at all :)

For C++ compiler we can simply tell: export it, as it would be for C compiler i.e.

  • extern "C" __declspec(dllexport)

but of course, this should be from third party code.. so, what to do:

The main problem: the same functions cannot be same from different compilers :(

TODO: just to find already existing solution for mangling names

Then we should provide support for example:

If user wants to call this: net::r_eg::Conari::UnLib::API::getSeven(void)

l.Mangling  = true; // switch of decoration
l.Prefix    = "net::r_eg::Conari::UnLib::API::"; //for all other functions

ushort val  = dll.getSeven<ushort>();  // to call unsigned short getD_Seven(void)
// before calling we should get final name: ?getD_Seven@API@UnLib@Conari@r_eg@net@@YAGXZ
// then simply call

Decoration for a C functions (and C++ if used C linkage):

In a 64-bit environment, functions are not decorated.

- -
__cdecl Underscore character (_) is prefixed to names, except when __cdecl functions that use C linkage are exported.
__stdcall Leading underscore (_) and a trailing at sign (@) followed by the number of bytes in the parameter list in decimal
__fastcall Leading and trailing at signs (@) followed by a decimal number representing the number of bytes in the parameter list
__vectorcall Two trailing at signs (@@) followed by a decimal number of bytes in the parameter list

well, I think for a C functions (and C++ if used C linkage), it should be solved simply:

Since more than one overloaded function is not possible at all:

Compiler Error C2733 - https://msdn.microsoft.com/en-us/library/5z9es6ec.aspx
error C2733: '...': second C linkage of overloaded function not allowed

    LIBAPI unsigned short int __stdcall get_SevenStdCall();      // _get_SevenStdCall@0
    LIBAPI unsigned short int __stdcall get_SevenStdCall(int a); // _get_SevenStdCall@4

we can try to get list of all exported functions from dll, and finally get _get_SevenStdCall@4 or _get_SevenStdCall@0, etc. :)

__fastcall:   @get_SevenFastCall@0
__vectorcall: get_SevenVectorCall@@0

but C++ mangling still TODO =/

now, Conari will do it all automatically for C functions, e.g.:

dlr.get_SevenStdCall<ushort>()   //->  _get_SevenStdCall@0
dlr.get_SevenFastCall<ushort>()  //->  @get_SevenFastCall@0

done. :p

C++ later...