好的,我有一个 DLL 函数声明为:
[DllImport(mDllName, EntryPoint = "SetParam")]
public static extern bool setParam(string param_name, ref IntPtr param_value);
Run Code Online (Sandbox Code Playgroud)
这个函数需要许多不同的参数,即在 C++ 中这就是你将如何使用它。
int i=2;
setParam("width", &i);
float k=2.5f;
setParam("factor", &f);
Run Code Online (Sandbox Code Playgroud)
所以我试图声明一个 C# 函数来调用这个 DLL api,我有一个用于指向整数大小写的指针:
public static void setWidth(int width)
{
IntPtr w = new IntPtr(width);
setParam("width", ref w);
}
Run Code Online (Sandbox Code Playgroud)
但是我不知道如何做第二个,我将一个指针作为 IntPtr 传递给浮点数。有任何想法吗?
public static void setFactor(float f)
{
IntPtr w = new IntPtr(f); // WHAT GOES HERE??
setParam("factor", ref w);
}
Run Code Online (Sandbox Code Playgroud)
除非有太多组合,否则我认为最好的方法是DllImport为各种参数类型简单地使用多个s。例如:
[DllImport(mDllName, EntryPoint = "SetParam")]
public static extern bool setParamInt32(string param_name, ref int param_value);
[DllImport(mDllName, EntryPoint = "SetParam")]
public static extern bool setParamSingle(string param_name, ref float param_value);
Run Code Online (Sandbox Code Playgroud)
然后您可以正确调用它们
var intVal = 42;
setParamInt32("param", ref intVal);
var floatVal = 42.0f;
setParamSingle("param", ref floatVal);
Run Code Online (Sandbox Code Playgroud)
ref IntPtr在任何一种情况下使用都是错误的 - 它起作用的唯一原因是在 32 位应用程序中,IntPtr内部是一个 32 位整数。但是,它应该是一个指针。正确使用应该是这样的:
[DllImport(mDllName, EntryPoint = "SetParam")]
public static extern bool setParam(string param_name, IntPtr param_value);
Run Code Online (Sandbox Code Playgroud)
请注意,ref不存在 -IntPtr已经是一个间接引用。
要调用它,您需要分配一些内存,并获取指向该内存的指针 - 或者,使用 aGCHandle直接引用托管对象:
var intValue = 42;
var handle = GCHandle.Alloc(intValue, GCHandleType.Pinned);
setParam("param", handle.AddrOfPinnedObject());
Run Code Online (Sandbox Code Playgroud)
当然,确保正确处理托管句柄 - 固定句柄对 GC 来说是一个巨大的痛苦。
手动将数据复制到非托管内存并返回也不是很难:
var ptr = Marshal.AllocCoTaskMem(sizeof(int));
try
{
Marshal.WriteInt32(ptr, 42);
setParam("param", ptr);
// If you need to read the value back:
var result = Marshal.ReadInt32(ptr);
}
finally
{
Marshal.FreeCoTaskMem(ptr);
}
Run Code Online (Sandbox Code Playgroud)
但我只是坚持使用自动编组,除非你有很好的理由不这样做。
| 归档时间: |
|
| 查看次数: |
4595 次 |
| 最近记录: |