用对元帅从C#字符串到C code数组/调用 [英] Marshal an array of strings from C# to C code using p/invoke

查看:231
本文介绍了用对元帅从C#字符串到C code数组/调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要通过C#字符串数组转换成C code

I need to pass an array of C# strings into C code

例C code

void print_string_array(const char** str_array, int length){
    for (int i = 0; i < length; ++i) {
        printf("Sting[%l] = %s\n", i, str_array[i]);
    }
}

C,它我试图#(这不工作)

C# that I have tried (This did not work)

string foo[] = {"testing", "one", "two", "three"};  
print_string_array(foo, foo.Length);

[DllImport(my_C_dll, CharSet = CharSet.Ansi)]
private static extern void print_string_array([In][MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPStr)] string[] sa, int length);

与System.AccessViolationException失败 System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

Fails with a System.AccessViolationException System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

我也尝试(这还没有工作)

I have also tried (This also did not work)

string[] foo = {"testing", "one", "two", "three"};  
IntPtr[] s_array = new IntPtr[foo.Length];

for(int i = 0; i < foo.Length; ++i) 
{
    s_array[i] = Marshal.StringToCoTaskMemAnsi(foo[i])
}
print_string_array( s_array, s_array.Length);

[DllImport(my_C_dll, CharSet = CharSet.Ansi)]
private static extern void print_string_array(IntPtr[] sa, int length);

这也失败了System.AccessViolationException System.AccessViolationException:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

This also fails with a System.AccessViolationException System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

任何一个知道如何从C#字符串数组传递到C?

Any one know how to pass an array of strings from c# to C?

编辑: 每建议新增的错误消息从大卫Heffernam。 更改为size_t为int用C code,因为它没有影响到我所试图做的。 仍然得到同样的错误。

Added error messages per suggestion from David Heffernam. Change size_t to int in C code since it did not affect what I was trying to do. Still get the same errors.

推荐答案

您可以简单地声明你的函数在C#这样的:

You can simply declare your function in C# like this:

[DllImport(my_C_dll, CallingConvention=CallingConvention.Cdecl)]
static extern void print_string_array([In] string[] str_array, IntPtr length);

由于这是写,你的C ++ code似乎使用 CDECL 调用约定。所以,你可能需要将C#的声明一致。我怀疑是你所面对的主要问题。

As it is written, your C++ code would appear to use the cdecl calling convention. So you may need to make the C# declaration match. I suspect that is the main problem you are facing.

另请注意,为size_t ,您可以用它为长度参数是32位宽的32位进程和64位宽在一个64位的过程。因此,正确的C#类型是的IntPtr 。个人而言,我会宣布它是 INT 同时在C ++和C#code。

Note also that size_t, which you use for the length parameter is 32 bits wide in a 32 bit process, and 64 bits wide in a 64 bit process. So the correct C# type is IntPtr. Personally I'd declare it to be int in both the C++ and C# code.

意见的最后一个字。当你遇到故障,包括你的问题的错误消息。我怀疑你的第一个code失败,此错误:

One final word of advice. When you encounter failures, include the error messages in your questions. I suspect your first code failed with this error:

要PInvoke的函数调用'MyApp的!MyApp.Program :: print_string_array有不平衡的堆栈。

A call to PInvoke function 'MyApp!MyApp.Program::print_string_array' has unbalanced the stack.

如果你已经包含在这个问题将是一个很大的帮助。

And if you had included that in the question it would have been a great help.

这篇关于用对元帅从C#字符串到C code数组/调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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