2013-10-18 57 views
0

我在写一个C#应用程序,它将大小为30的空字符串数组传递给C++ DLL。该字符串数组需要在DLL中填充并返回给C#应用程序。将C#中的字符串数组传递给C++ DLL函数并将其填充到DLL中并返回

我的代码我观察DLL函数调用结束时的内存损坏。

我的C++ DLL代码如下。请帮助我。提前致谢。

SAMPLEDLL_API BOOL InitExecution (wchar_t **paszStrings, int count) 
{ 
    for (int i = 0 ; i < count; i++) 
    { 
     mbstowcs(*(paszStrings + i), "Good",4); 
     //*(paszStrings + i) = "Good"; 
    } 
return TRUE; 
} 

我的C#代码是

string[] names = new[] { "Britto", "Regis" }; 
if (Wrapper1.InitExecution(ref names, names.Length) == 1) 
    MessageBox.Show("Passed"); 

[DllImport("MFCLibrary1.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern UInt32 InitExecution(ref string[] Names, int count); 

谢谢。

+0

C#字符串是不可变的。尝试传递一个'StringBuilder'。 – Romoku

+0

或者使用BSTR,而不必决定要分配多少内存 –

回答

1

为了使这种当前的方法工作,你需要通过StringBuilder实例,而不是string。这是因为数据是从主叫方流向被叫方的。这些字符串是参数。这意味着调用者必须为每个字符串分配缓冲区,并知道缓冲区需要多大。

这里使用BSTR更容易。这使您可以在本机代码中分配字符串,并让它们在托管代码中解除分配。这是因为BSTR被分配在共享的COM堆上,并且p/invoke编组人员理解它们。进行这种轻微的改变意味着来电者不需要知道弦线有多大。

的代码应该是这样的:

SAMPLEDLL_API BOOL InitExecution(BSTR* names, int count) 
{ 
    for (int i = 0 ; i < count; i++) 
     names[i] = SysAllocStr(...); 
    return TRUE; 
} 

和C#的方面,你写这样的:

[DllImport(@"mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern bool InitExecution(
    [Out] IntPtr[] names, 
    int count 
); 

然后你有一些工作从BSTR元帅以C#string

IntPtr[] namePtrs = new IntPtr[count]; 
InitExecution(namePtrs, namePtrs.Length); 
string[] names = new string[namePtrs.Length]; 
for (int i = 0; i < namePtrs.Length; i++) 
{ 
    names[i] = Marshal.PtrToStringBSTR(namePtrs[i]); 
    Marshal.FreeBSTR(namePtrs[i]); 
} 
相关问题