将带有字符串数组的C#结构传递给C ++函数,该函数接受void *(对于c#结构)和char **(对于c#字符串数组) [英] Passing C# structure with string array to c++ function which accepts void * for c# structure and char** for c# string array

查看:124
本文介绍了将带有字符串数组的C#结构传递给C ++函数,该函数接受void *(对于c#结构)和char **(对于c#字符串数组)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将带有字符串数组的 C#结构发送到C ++函数,该函数接受void *(对于c#结构)和char **(对于c#结构字符串数组成员).

I want to send a C# structure with string array to a C++ function which accepts void * for the c# structure and char** for the c# structure string array member.

我能够将结构发送到c ++函数,但是问题是无法从c ++函数访问c#结构的字符串数组数据成员.当单独发送字符串数组时,我能够访问数组元素.

I was able to send the structure to c++ function,but the issue is , not able to access the string array data member of c# structure from c++ function. When sending the string array separately,i was able to access the array elements.

示例代码为-

C# Code:

[StructLayout(LayoutKind.Sequential)]
public struct TestInfo
{
    public int TestId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public String[] Parameters;
}

[DllImport("TestAPI.dll", CallingConvention = CallingConvention.StdCall, EntryPoint    "TestAPI")]
private static extern void TestAPI(ref TestInfo data);

static unsafe void Main(string[] args)
{
TestInfo  testinfoObj = new TestInfo();
testinfoObj.TestId = 1;
List<string> names = new List<string>();
names.Add("first");
names.Add("second");
names.Add("third");
testinfoObj.Parameters=names.ToArray();
TestAPI(ref testinfoObj);
}



VC++ Code:

/*Structure with details for TestInfo*/
typedef struct TestInfo
{
int  TestId;
char **Parameters;
}TestInfo_t;

//c++ function
__declspec(dllexport) int TestAPI(void *data)
{
TestInfo *cmd_data_ptr= NULL;
cmd_data_ptr = (TestInfo) data;
printf("ID is %d \r\n",cmd_data_ptr->TestId);//Working fine

for(i = 0; i < 3; i++)
printf("value: %s \r\n",((char *)cmd_data_ptr->Parameters)[i]);/*Error-Additional     information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt*/
}

在分析内存堆栈时,观察到我打印时 ((char *)cmd_data_ptr-> Parameters,第一个数组元素("first")正在打印, 但是使用((char *)cmd_data_ptr-> Parameters)[i],则无法访问元素,并且上述异常即将到来.

When analyzing the memory stack, it is observed that,when i print ((char *)cmd_data_ptr->Parameters), the first array element("first") is getting printed, but using ((char *)cmd_data_ptr->Parameters)[i], not able access elements and above mentioned exception is coming.

结构内存地址包含所有结构元素的地址,但是从c ++访问数据时,它仅访问字符串数组的第一个元素.

The structure memory address contains address of all the structure elements,but while accessing the data from c++,it is accessing only the first element of the string array.

推荐答案

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public String[] Parameters;

是一个内联数组.匹配的C ++声明为:

is an inline array. The C++ declaration that matches is:

char* Parameters[2];

但是您正在尝试将其匹配到:

But you are trying to match it to:

char** Parameters;

那是完全不同的.

您将需要手动封送.在C#结构中,将Parameters声明为IntPtr.然后使用Marshal.AllocHGlobal分配本机内存以保存指针数组.然后使用指向您的字符串的指针填充这些指针.

You will need to marshal this by hand. In the C# struct declare Parameters to be IntPtr. Then allocate native memory with Marshal.AllocHGlobal to hold an array of pointers. And then populate those pointers with pointers to your strings.

[StructLayout(LayoutKind.Sequential)]
public struct TestInfo
{
    public int TestId;
    public IntPtr Parameters;
}

static void Main(string[] args) // no need for unsafe
{
    TestInfo testInfo;
    testInfo.TestId = 1;
    testInfo.Parameters = Marshal.AllocHGlobal(2*Marshal.SizeOf(typeof(IntPtr)));
    IntPtr ptr = testInfo.Parameters;
    Marshal.WriteIntPtr(ptr, Marshal.StringToHGlobalAnsi("foo"));
    ptr += Marshal.SizeOf(typeof(IntPtr));
    Marshal.WriteIntPtr(ptr, Marshal.StringToHGlobalAnsi("bar"));
    TestAPI(ref testinfoObj);
    // now you want to call FreeHGlobal, I'll leave that code to you
}

另一种选择是使用固定的IntPtr []并将其放在testInfo.Parameters中.

An alternative would be to use a pinned IntPtr[] and put that in testInfo.Parameters.

这篇关于将带有字符串数组的C#结构传递给C ++函数,该函数接受void *(对于c#结构)和char **(对于c#字符串数组)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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