如何调用从 csharp 获取结构指针参数的 c lib fn

问题描述 投票:0回答:1

从c头中提取:

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

值得注意的是,c“字符串”不能依赖任何特定的编码,因此可能无法将它们表示为 C# 字符串,我认为

byte[]
是正确的,但我不确定如何指示长度不是在编译时已知。

Trying to express the c struct in 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);
c# c pointers struct ffi
1个回答
0
投票

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

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ArgvArgcResult
{
    public string buffer;
    public nint 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

如果实际上 C 函数使用

buffer
作为它自己的缓冲区,那么你必须传入一个内存指针

[StructLayout(LayoutKind.Sequential)]
public struct ArgvArgcResult
{
    public nint buffer;
    public nint argv;
    public ulong argc;
}
var result = new ArgvArgcResult();
try
{
    result.buffer = Marshal.AllocHGlobal(someSizeHere);
    // fill buffer??
    // call function, handle strings
}
finally
{
    Marshal.FreeHGlobal(result.buffer);
}
© www.soinside.com 2019 - 2024. All rights reserved.