error during dll-function call from C# code
I created dll in c++ and wanted to call function from it using c#. I has an error if function, which program calls, returns string. Dll code:
#include <string>
using开发者_如何学编程 namespace std;
#define EXPORT_API extern "C" __declspec(dllexport)
EXPORT_API void DllFunc()
{
MessageBoxA(0,"DDL box", "Yeah!", 0);
}
EXPORT_API string DllFuncStr()
{
return "testStr";
}
C# application code:
[DllImport("dllka.dll")]
static extern void DllFunc();
[DllImport("dllka.dll")]
static extern string DllFuncStr();
private void btnStart_Click(object sender, RoutedEventArgs e)
{
DllFunc();
string str = DllFuncStr();
}
"DllFunc();" - works nice, but on line "string str = DllFuncStr();" i had an error:
The runtime has encountered a fatal error. The address of the error was at 0x5e6dceca, on thread 0x16b0. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
What is wrong with string type? How to fix this problem?
You can't marshal std::string from C++ to C#. Instead either use a zero-terminated string marshalled with StringBuilder, or return a BSTR.
The BSTR approach is quite simple. If you prefer zero-terminated string then look on the web for sample P/Invokes from Win32 APIs, e.g. GetWindowText().
You are exporting from C++ with cdecl calling convention, but using stdcall in the C# code. You'll need to match those up once you have sorted the data type marshalling out. It doesn't matter which you use, so long as it's the same at both ends.
You will also need to broach the fact that your C++ code uses char (8 bit encoding) and C# uses Windows native UTF-16.
If it was me, I'd do it with a BSTR, as I outline in this answer to another question.
As David said, c++ std::string and c# string are different things. I did it following way in my application:
c++ DLL code:
EXPORT_API void DllFuncStr(char* sRetText, int nCapacity)
{
if(!sRetText)
return;
std::string sRetTextStr("testStr");
strcpy_s(sRetText, nCapacity, sRetTextStr.c_str());
return;
}
c# application code:
[DllImport("dllka.dll")]
static extern bool DllFuncStr(StringBuilder sStrBuilder, int nCapacity);
private void btnStart_Click(object sender, RoutedEventArgs e)
{
StringBuilder strBuilder = new StringBuilder(50);
DllFuncStr(strBuilder, strBuilder.Capacity);
string str = strBuilder.ToString();
}
(Thank you Hans for suggestions. I will repair this thing in my application, too)
精彩评论