【问题标题】:How to marshall struct parameter byRef, when importing C DLL into C# console application?将 C DLL 导入 C# 控制台应用程序时,如何编组结构参数 byRef?
【发布时间】:2020-08-26 09:39:41
【问题描述】:

我将一个 C DLL 导入到我的 C# 程序中,并且必须编组一个 ByRef 结构参数。

这是 C 中函数的签名:

extern "C" {
int __stdcall FuncToImport(const char* stringToMarshall, StructFromDLL* structToMarshall);
...
...
...
}

这是我尝试在 C# 中导入它的方式

[DllImport("ImportedDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FuncToImport(string stringToImport, ref HandleRef structToImport);

在 Main 中调用它时出现异常: System.Runtime.InteropServices.MarshalDirectiveException: '"parameter #7" cannot be marshalled: HandleRefs cannot be marshalled as ByRef or not managed/managed Parameter..'

正确编组参数的可能方法是什么?

【问题讨论】:

  • HandleRef 是一个非常神秘的选择。您需要在 C# 代码中声明该结构。

标签: c# c import marshalling dllimport


【解决方案1】:

试试这个

[DllImport("ImportedDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FuncToImport(string stringToImport, IntPtr structToImport);

private static IntPtr StructToPointer<T>(T Struct) where T : struct
{
    //Allocates the necessary memoryspace and creates a pointer to this memory
    int rawsize = Marshal.SizeOf(Struct);
    IntPtr pointer = Marshal.AllocHGlobal(rawsize);

    //Writes the current data from the struct to the allocated memory
    Marshal.StructureToPtr(Struct, pointer, false);

    return pointer;
}

private static T PointerToStruct<T>(IntPtr pointer) where T : struct
{
    //Creates a Struct of the type of T from the pointed memory
    T Struct = Marshal.PtrToStructure<T>(pointer);
    //Frees the allocated memory
    Marshal.FreeHGlobal(pointer);
    return Struct;
}

IntPtr pointer = StructToPointer(structToImport);

FuncToImport("", pointer);

structToImport = PointerToStruct<Type of structToImport>(pointer);

【讨论】:

  • 如果 marshaler 不能使用 ref 传递的结构自动封送结构,那么这也会失败。 Q 中的实际问题与HandleRef 的(误)使用有关。
  • 我不知道你在说什么我一直都在这样做。你只需要在 C# 和 C 中定义相同的结构。我不是在这里封送结构我只是给 C DLL 一个指向字节 [] 的指针,我仍然可以读取 C DLL 函数完成的指针。
  • 是的,但是提问者没有定义结构,这就是实际问题。当您可以在 pinvoke 参数声明中执行 ref StructFromDLL value 时,使用 IntPtr 进行所有这些手动编组是没有意义的。
  • 我知道这是真正的问题,但我想给他一个可行的解决方案,而不仅仅是解释问题所在,尤其是因为有人已经指出了这一点。然而,在测试之后,我必须承认我的解决方案虽然有效,但不必要地复杂。我不知道你可以直接使用像结构这样的复杂变量。你生活和学习。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多