Marshall char** to string problem calling unmanaged code from managed code
I've this C++ function,
bool MyClass::my_function(int num, TCHAR** filepath)
I've expose the function as
extern "C"
{
__declspec(dllexport) bool MyFunction(int num, char* filepath[])
{
OutputDebugStringA("--MyFunction--");
TCHAR **w_filepath = (TCHAR **)calloc(num, 2* sizeof(TCHAR **));
for(int i = 0; i < num; i++)
{
OutputDebugStringA(filepath[i]);
开发者_Go百科 int len = strlen(filepath[i]) + 1;
w_filepath[i] = (TCHAR *)calloc (1, len);
ctow(w_filepath[i], filepath[i]); // converts char to WCHAR
}
bool ret = MyClass.my_function(num, w_filepath);
OutputDebugStringA("End -- MyFunction --");
free(w_filepath);
return ret;
}
}
I've C# wrapper as
[DllImport("MyDll.dll")]
public static extern bool MyFunction(int num, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr)] string[] filepath);
In C#, i call Myfunction as
string [] filepath = { "D:\\samplefile\\abc.txt", "D:\\samplefile\\def.txt"}
MyFunction(2, filepath)
In C++ function, it gets only first character of filepath. For example, from above call if i print in C++ code using
OutputDebugStringA
it prints only D for both first and second.
If i remove
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr)]
from c# wrapper I'll get Access violation error in
w_filepath[i] = (TCHAR *)calloc (1, len)
for second file.
Please help me.
1) w_filepath[i] = (TCHAR *)calloc (1, len);
- calloc requires size in bytes, so it should be w_filepath[i] = (wchar_t *)calloc (1, len*sizeof(wchar_t));
2) data from c# comes as wchar_t*, so you don't need converting routines at all , and should change function declaration to
__declspec(dllexport) bool MyFunction(int num, wchar_t* filepath[])
精彩评论