元帅使用P/Invoke从C#到C代码的一系列字符串
Marshal an array of strings from C# to C code using p/invoke
我需要将C#字符串数组传递到C代码
示例C代码
void print_string_array(const char** str_array, int length){
for (int i = 0; i < length; ++i) {
printf("Sting[%l] = %sn", 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:尝试读取或写下受保护的内存。这通常表明其他内存已损坏。
我也尝试过(这也没有起作用)
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的建议添加了错误消息。将size_t更改为c代码中的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
。
最后一个建议。当您遇到失败时,将错误消息包括在问题中。我怀疑您的第一个代码失败了此错误:
调用pinvoke函数'myapp!myapp.program.program :: print_string_array'的堆栈不平衡。
,如果您将其包括在问题中,那将是一个很大的帮助。
您的第二次尝试非常接近。尝试以下内容:
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.StringToHGlobalAnsi(foo[i])
}
GCHandle gH = GCHandle.Alloc(s_array, GCHandleType.Pinned);
print_string_array( gH.AddrOfPinnedObject(), s_array.Length);
gH.Free();
for(int i = 0; i < foo.Length; ++i)
{
Marshal.FreeHGlobal(s_array[i])
}
[DllImport(my_C_dll, CharSet = CharSet.Ansi)]
private static extern int print_string_array(IntPtr sa, int length);
相关文章:
- 编译包含字符串的代码时遇到问题
- 为什么这个 c++ 代码打印出长度 5,当我打印出字符串时,程序会自动终止?
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 我无法在 qt 的C++代码中定义字符串
- 从 C 样式字符串中删除子字符串 "in place" 在C++代码中
- 有人可以解释一下这段代码如何能够反转字符串
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符
- 如何用符合C++核心准则的代码替换C风格的字符串解析
- C++/CLI访问字符串::来自非CLI代码的格式
- MSVC UTF8字符串编码使用了不正确的代码点
- C++指向对象的指针堆数组中,如何将字符串传递给特定对象?有一些代码请看一下:
- 将浮点数转换为字符串时如何加快此代码的速度?
- C++代码,用于在用户插入的字符串的每个元音之后插入一对字符
- 如何获取包含 NULL 字符的外壳代码字符串的长度
- 为什么 for 循环只接受这个简单代码中的最后一个字符串?
- 返回所有代码 - 字符串
- 我能做些什么来加速这个代码(字符串相似性)
- 不知道该为函数的最后一个代码字符串写什么
- 可以将代码字符串传递到c++宏中吗?