Marshall字符**从字符串问题从托管代码调用非托管代码 [英] Marshall char** to string problem calling unmanaged code from managed code

查看:158
本文介绍了Marshall字符**从字符串问题从托管代码调用非托管代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个C ++函式,

  bool MyClass :: my_function(int num,TCHAR ** filepath)

我已将函数公开为

  externC
{
__declspec(dllexport)bool MyFunction(int num,char * filepath [])
{
OutputDebugStringA( -MyFunction--);
TCHAR ** w_filepath =(TCHAR **)calloc(num,2 * sizeof(TCHAR **));
for(int i = 0; i {
OutputDebugStringA(filepath [i]);
int len = strlen(filepath [i])+ 1;
w_filepath [i] =(TCHAR *)calloc(1,len);
ctow(w_filepath [i],filepath [i]); // converted char to WCHAR
}

bool ret = MyClass.my_function(num,w_filepath);
OutputDebugStringA(End - MyFunction - );
free(w_filepath);
return ret;
}
}

我有C#封装为

  [DllImport(MyDll.dll)] 
public static extern bool MyFunction(int num,[MarshalAs(UnmanagedType.LPArray,ArraySubType = UnmanagedType.LPTStr)] string [] filepath);

在C#中,我调用Myfunction作为

  string [] filepath = {D:\\samplefile\\abc.txt,D:\\samplefile\\def.txt} 
MyFunction(2,filepath)

在C ++函数中,它只获取文件路径的第一个字符。
例如,从上面调用如果我使用

打印C ++代码

  OutputDebugStringA 



只会为第一个和第二个打印D.



/ p>

  [MarshalAs(UnmanagedType.LPArray,ArraySubType = UnmanagedType.LPTStr)] 
pre>

来自c#wrapper
我将在

中获取Access违规错误。

 code> w_filepath [i] =(TCHAR *)calloc(1,len)

第二个档案。



请帮助我。

解决方案

1) code> w_filepath [i] =(TCHAR *)calloc(1,len); - calloc需要大小(以字节为单位),因此应为 w_filepath [i] = (wchar_t *)calloc(1,len * sizeof(wchar_t));



2)c#中的数据来自wchar_t *不需要转换例程,应该将函数声明更改为

  __ declspec(dllexport)bool MyFunction(int num,wchar_t * filepath [])


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]);
            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[])

这篇关于Marshall字符**从字符串问题从托管代码调用非托管代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆