我需要将 C# 字符串数组传递给 C 代码
示例 C 代码
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#(没用)
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:试图读取或写入 protected 内存。这通常表明其他内存已损坏。
我也试过了(这个也没用)
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 : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
有人知道如何将字符串数组从 C# 传递到 C 吗?
更新: 根据 David Heffernan 的建议添加了错误消息。 在 C 代码中将 size_t 更改为 int,因为它不会影响我尝试做的事情。 仍然得到相同的错误。
最佳答案
您可以像这样在 C# 中简单地声明您的函数:
[DllImport(my_C_dll, CallingConvention=CallingConvention.Cdecl)]
static extern void print_string_array([In] string[] str_array, IntPtr length);
如所写,您的 C++ 代码似乎使用 cdecl
调用约定。因此,您可能需要使 C# 声明匹配。我怀疑这是您面临的主要问题。
另请注意,用于 length
参数的 size_t
在 32 位进程中为 32 位宽,在 64 位进程中为 64 位宽。所以正确的 C# 类型是 IntPtr
。我个人会在 C++ 和 C# 代码中将其声明为 int
。
最后的忠告。当您遇到失败时,请在您的问题中包含错误消息。我怀疑您的第一个代码因此错误而失败:
A call to PInvoke function 'MyApp!MyApp.Program::print_string_array' has unbalanced the stack.
如果您在问题中包含了这一点,那将是一个很大的帮助。
关于c++ - 使用 p/invoke 将字符串数组从 C# 编码到 C 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13317931/