DllImport如何通过引用获取单个值

时间:2012-04-11 18:30:02

标签: c# dllimport ref intptr

使用指针params能够获得输出参数的适当签名/ marshall属性是什么?到目前为止,我试过这个:

// Function to calculate the norm of vector. !0 on error.
// int err_NormVec(int size, double * vector, double * norm)
[DllImport("vectors.dll")]
int err_NormVec(int size, double[] vector, ref double norm)

之前的方法并没有从C回弹到.NET的值。我还尝试使用带有IntPtr签名的固定GCHandle。

[DllImport("vectors.dll")]
int err_NormVec(int size, double[] vector, IntPtr norm)

public void doSomething()
{
   double norm = 0;
   // ...
   GCHandle handle = GCHandle.Alloc(norm, GCHandleType.Pinned);
   int status = err_NormVec(vector.Lenght, vector, handle.AddrOfPinnedObject());
   // ... clean gchandle, check status and so on
}

在这种情况下,我得到了值,但是在GCHandle.Target上,而不是原始规范。这很烦人。我希望能够将自己的标准固定在自己身上,而不仅仅是副本。

使用指针返回值的适当签名是什么?是否有支持的方法将IntPtr设置为int值?

1 个答案:

答案 0 :(得分:1)

这对我有用(应该如此):

//C++ DLL (__stdcall calling convention)
extern "C" __declspec(dllexport) void Foo(double *result) {
    *result = 1.2;
}

//C#    
class Program
{
    [DllImport( "Snadbox.dll", CallingConvention=CallingConvention.StdCall )]
    static extern void Foo( ref double output );

    static void Main( string[] args )
    {
        double d = 0;           
        Foo( ref d );

        Console.WriteLine( d ); // prints "1.2"         
    }
}

使用double关键字传递ref就足够了。因此,我被认为在实施中存在错误(或误解)。你能为我们发布实施吗?

此外,您可能正在使用默认调用约定(cdecl)构建C ++版本,但.NET正在使用StdCall。你确定这些排队吗?如果他们混在一起你可能会崩溃,但是没有保证。例如,在我的示例中,如果我将C ++端更改为cdecl,则将out参数读回为0.