C # and C ++, runtime error when calling C ++ dll from C #

I wrote a C ++ DLL wrapper to call C #. The DLL was tested and worked great with my C ++ test program.

Now integrated with C #, I got a runtime error and crashed. You cannot use the debugger to view more detailed information.

The C ++ side has only one method:

#ifdef DLLWRAPPERWIN32_EXPORTS
#define DLLWRAPPERWIN32_API __declspec(dllexport)
#else
#define DLLWRAPPERWIN32_API __declspec(dllimport)
#endif

#include "NB_DPSM.h"

extern "C" {
 DLLWRAPPERWIN32_API int WriteGenbenchDataWrapper(string fileNameToAnalyze, 
  string parameterFileName,  
  string baseNameToSaveData,
  string logFileName,
  string& message) ;
}

on the C # side there is a definition

[DllImport("..\\..\\thirdParty\\cogs\\DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(string fileNameToAnalyze, 
              string parameterFileName,  
              string baseNameToSaveData,
              string logFileName, 
              ref string message);

and call:

 string msg = "";
    int returnVal = WriteGenbenchDataWrapper(rawDataFileName, 
                   parameterFileName, outputBaseName, logFileName, ref msg);

I think there must be something wrong with the last parameter of the function. string&in C ++ should be ref stringin C #?

EDIT:

Do we really need extern "C"?

EDIT 2:

extern "C dll, EntryPointNotFoundException. dll DLL Export Viewer, , "int __cdecl WriteGenbenchDataWrapper ( std::..." "__cdecl"?

+3
2

PInvoke. Marsheling

#. , StringBuilder , - .

[DllImport("DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(string fileNameToAnalyze, 
                                                    string parameterFileName,   
                                                    string baseNameToSaveData,
                                                    string logFileName, 
                                                    StringBuilder message
                                                    int messageLength );

( ) , , , , ,

[DllImport("DLLWrapperWin32.dll")]
public static extern int WriteGenbenchDataWrapper(in string fileNameToAnalyze, 
                                                    in string parameterFileName,   
                                                    in string baseNameToSaveData,
                                                    in string logFileName, 
                                                    out string message );

C/++ -

extern "C" // if this is a C++ file to turn off name mangling for this function only
int WriteGenbenchDataWrapper( char * fileNameToAnalyze, 
                              char * parameterFileName,   
                              char * baseNameToSaveData,
                              char * logFileName, 
                              char ** message ) {
  string internalMessage;
  SomeFunc( internalMessage ); // these functions won't have extern "C" applied
  * message = (char *)::CoTaskMemAlloc(internalMessage.length()+1); 
  strcpy(* message, internalMessage.c_str());
}

unicode/ansi , . [MarshalAsAttribute (UnmanagedType.LPWSTR)]

".. \..\thirdParty\cogs"

+3

++:

"C". ++ , ( ). "C" , .

__stdcall. , #, , , __stdcall .

, , , const char * ++.

, . , , (const char * IntPtr).

#:

String const char *, int int .. , Microsoft -, , .

, ANSI. Marshal.PtrToStringAnsi().

:

++:

extern "C" __declspec(dllexport) const char* __stdcall GetCompany(const char *In) {
  return MyGetCompany(In); // Calls the real implementation
}

#:

[DllImport("TheDLL.dll", EntryPoint = "GetCompany")]
private static extern IntPtr privGetCompany(String In);

// Call this one, not the one above:
public String GetProvince(String In)
{
  return Marshal.PtrToStringAnsi(privGetCompany(In));
}

, 64- , "Any CPU" 64- #, 64- DLL. 32- DLL, (x86).

, , , #, , DLL , mangling . .

+1

Source: https://habr.com/ru/post/1750550/


All Articles