如何调用clib fn,它从csharp中获取结构指针参数

dldeef67  于 2023-04-29  发布在  其他
关注(0)|答案(1)|浏览(87)

从c header中提取:

struct ArgvArgcResult {
  char*  buffer;
  char** argv;
  uint   argc;
};
bool get_argv_and_argc_of_pid(pid_t pid, struct ArgvArgcResult* result);

值得注意的是,c“字符串”不能依赖于任何特定的编码,因此将它们表示为C#字符串可能是不可能的,相反,我认为byte[]是正确的,但我不确定如何表明长度在编译时未知。
尝试用C#表达c结构体时,我不知道char*char**使用什么类型:

[StructLayout(LayoutKind.Sequential)]
public struct ArgvArgcResult {
    public char*  buffer;
    public char** argv;
    public ulong  argc;
}

当从c#调用dllimport的c fn时,指向结构体的指针是什么样子的?

[DllImport("libgetargv.dylib", CallingConvention = CallingConvention.Cdecl)] static extern bool get_argv_and_argc_of_pid(nuint pid, struct ArgvArgcResult* result);
6yoyoihd

6yoyoihd1#

char在C/C++中是8位的,所以你需要byte。您可以将其作为byte[]数组传递,但char*也可以作为ANSI字符串传递。您似乎在进行自己的内存管理,因此可以将argv作为指针传递给指针。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ArgvArgcResult
{
    public string buffer;
    public IntPtr argv;
    public ulong argc;
}

将结构体作为ref传递

[DllImport("libgetargv.dylib", CallingConvention = CallingConvention.Cdecl)]
static extern bool get_argv_and_argc_of_pid(
  nuint pid,
  ref ArgvArgcResult result);

当您使用它时,您可以像这样读取argv

for (var i = 0; i < result.argc; i++)
{
    var ptr = Marshal.ReadIntPtr(argv, IntPtr.Size * i);
    var str = Marshal.PtrToStringAnsi(ptr);
    // do stuff
}
// don't forget to free memory

相关问题