How to set up a C++ function so that it can be used by p/invoke?

前端 未结 6 633
旧巷少年郎
旧巷少年郎 2020-12-30 13:01

Hopefully this is a brainlessly easy question, but it shows my lack of expertise with C++. I\'m a C# programmer, and I\'ve done extensive work with P/Invoke in the past wit

相关标签:
6条回答
  • 2020-12-30 13:18

    Do something likes this:

    #define EXPORT extern "C" __declspec(dllexport)
    

    And then declare any function with the EXPORT keyword, for example an c++ function

    BOOL getString(TCHAR* string, DWORD size);
    

    would become

    EXPORT BOOL getString(TCHAR* string, DWORD size);
    

    then the fun part: Go to your VS console and type :

    dumpbin /EXPORTS <PATH_TO_GENERATED_DLL>
    

    and you'l see the mangled name and ordinal of all your easily exported functions, then it's just an matter o pInvoking them

    0 讨论(0)
  • 2020-12-30 13:18

    Build all project with Win32 platform and appropriate bit (e.g. x86 or x64) build option.

    0 讨论(0)
  • 2020-12-30 13:23

    Extending Reed's correct answer.

    Another issue you can run into when exposing a C++ function via PInvoke is using invalid types. PInvoke can really only support marshalling of primitive types and plain old data struct / class types.

    For example, suppose TestFunc had the following signature

    void TestFunc(std::string input);
    

    Even adding extern "C" and __declspec(dllexport) would not be enough to expose the C++ function. Instead you would need to create a helper function which exposed only PInvoke compatible types and then called into the main function. For example

    void TestFunc(const std::string& input) { ... }
    
    extern "C" _declspec(dllexport)  void TestFuncWrapper(char* pInput) {
      std::string input(pInput);
      TestFunc(input);
    }
    
    0 讨论(0)
  • 2020-12-30 13:24

    The C++ compiler modifies the names of your functions to incorporate information about the parameters and return types. This is called name mangling. On the other hand, the C compiler doesn't mangle your function names.

    You can tell the C++ compiler to work as a C compiler using extern "C":

    extern "C" __declspec(dllexport) bool TestFunc { return true; }
    

    To call functions from C# using P/Invoke, your names must not be mangled. Therefore, you can actually export C functions to C#. If you want the functionality to be implemented in C++, you can write a C function that just calls the C++ function implementing the functionality.

    0 讨论(0)
  • 2020-12-30 13:28

    You'll want to use extern "C" as well as __declspec(export), like so:

    extern "C" _declspec(dllexport)  bool TestFunc()
    {
        return true;
    }
    

    For full details, see MSDN on Marshalling Types.

    0 讨论(0)
  • 2020-12-30 13:40

    You have to expose this function with extern "C" otherwise the name gets mangled.

    0 讨论(0)
提交回复
热议问题