I connect the C ++ library to the C # project, the library is fully working. Guide to connecting took here .

[DllImport("C:\\Users\\Zaki\\Desktop\\SetsGen.dll", CallingConvention = CallingConvention.Cdecl)] public static extern string GetSets(string ids, int power); public void DllSub(string param) { try { string myAns = GetSets(param, 3); string[] tokens = myAns.Split('/'); foreach (var token in tokens) { Console.WriteLine(token); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } 

The native signature of the GetSets function in Dll looks like this:

 std::string GetSets(std::string ids, int power) 

I get an exception when accessing the ported GetSets function:

An unhandled exception of type 'System.AccessViolationException' occurred in Test.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

What could be the reasons and how to fix it?

    2 answers 2

    The reasons may be different:

    1. Error in the implementation of the native function. To eliminate it, try to make an empty GetSets and rebuild the DLL.

    2. Compatibility problems DLL and C # code. There was a case when a DLL compiled in C ++ Builder led to errors at the execution stage. Reassembly by MS compiler solved the problem on the vine.

    3. Wrong arguments are passed to the function. See line marshaling .

    If the signature of a native function contains complex types from the standard C ++ library (including std::string ), using such a function in P / Invoke will be problematic (read as impossible). Different compilers implement standard classes in different ways, so it is quite dangerous to transfer such types between modules.

    In this case, the most correct solution will be to export a function that accepts const char* (C string), and then in the guts of the DLL you can already use std::string for convenience.

    • Checked point 1: the same error; Checked point 2: even with different settings Debug / Release x86 / x64 the same error; I do not know how to deal with the 3rd reason? - zaki hatfild
    • @zakihatfild without changing the function signature does not work. std::string although std , but P/Invoke does not allow this to turn. - αλεχολυτ
    • and the C # compiler will not swear if in the import of the function from the dll I write the signature with the parameter const char *? - zaki hatfild
    • @zakihatfild string in c# code matches const char* in c++ . At least in my code this works without complaints. There is another question on enSO , it may come in handy. - αλεχολυτ
    • @alexolut, you are wrong. The C # string type is Unicode encoded and corresponds to the wchar_t type ( std::wstring ). Another thing is the type used in marshalling. Take a look at the first link from my answer. - Alexis

    There are several problems here, one of which is the return value from the native function ( std::string ). In a nutshell - standard methods you do not return a string from the native method result.

    The second problem is that strings in C # are encoded as Unicode, and the native std::string is encoded as ASCII. I advise you to use std::wstring in the native method, CharSet = CharSet.Unicode in marshalling and return the result as shown here:

    PS With C ++ CLI everything is much better in terms of marshalling.