从c#代码传递结构引用来调用接受其原型中的结构引用的c ++ DLL函数

时间:2011-03-23 08:14:09

标签: c# c++ dll reference parameter-passing

我在c ++ DLL中有一个具有以下原型的函数

int function(RefPar &params);

如何使用“DLLImport”从c#程序调用此函数。

当我在下面尝试时,AccessViolationException在visual studio 2008中运行时发生了..

[DllImport("VistaGMMDLL.dll", EntryPoint = "function"]
unsafe static extern int function(ref RefPar params);

并称为..

int ret=function(ref params);
  

注意:RefPar结构有很多   无符号整数值和1个枚举   价值作为其成员。

请任何人帮我正确调用该功能..

3 个答案:

答案 0 :(得分:0)

尝试这种方式:

[StructLayout(LayoutKind.Sequential)]
public struct RefPar
{
    UInt32 uint1;
    UInt32 unti2;
    ....
} 


[DllImport("VistaGMMDLL.dll", EntryPoint = "function"]
unsafe static extern int function(IntPtr params);

//calling

//fill the refParStructure
//create the IntPtr  

refParStruct rs = new RefPar();

IntPtr refparPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(refPar)));


Marshal.StructureToPtr(refParStruct, refparPtr,false);
ret=function(refParPtr);

如果您需要更多详细信息,请告诉我

答案 1 :(得分:0)

有几件事情在我身上跳了出来。首先,我不明白为什么你需要使用不安全的。其次,你可能有一个调用约定不匹配,C ++中的cdecl和C#中的stdcall。

我会这样做:

<强> C ++

struct RESOURCE_PARAMETERS{
    unsigned int uSurfaceHeight;
    unsigned int uSurfaceDepth;
    unsigned int uSurfaceWidth;
    unsigned int uMSAAHeight;
    unsigned int uMSAAWidth;
    unsigned int uArraySize;
    unsigned int uNumSamples;
    unsigned int uMaxLod;
    unsigned int uBpp;
    unsigned int uprefFlag;
    unsigned int uusageFlag;
    RESOURCE_TYPE_REC ResourceType;
    int ResourceFormat;
    int iBuildNumber;
};

int function(RefPar &parameters)
{
}

<强> C#

[StructLayout(LayoutKind.Sequential)]
public struct RESOURCE_PARAMETERS
{
    uint uSurfaceHeight;
    uint uSurfaceDepth;
    uint uSurfaceWidth;
    uint uMSAAHeight;
    uint uMSAAWidth;
    uint uArraySize;
    uint uNumSamples;
    uint uMaxLod;
    uint uBpp;
    uint uprefFlag;
    uint uusageFlag;
    [MarshalAs(UnmanagedType.U4)]
    ResourceType ResourceType;
    int ResourceFormat;
    int iBuildNumber;
} 

[DllImport("VistaGMMDLL.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int function(ref RESOURCE_PARAMETERS parameters);

RESOURCE_PARAMETERS parameters = new RESOURCE_PARAMETERS();
int result = function(ref parameters);

我不确定枚举在C ++大小上有多大。这就是为什么我在C#代码中放置了一个明确的MarshalAs。如果它只是一个字节,那么请改用UnmanagedType.U1。我相信你明白了。

如果您的C ++函数将其参数视为输入/输出参数,那么在C#端使用ref是正确的。如果它实际上是一个out参数,那么将代码更改为:

[DllImport("VistaGMMDLL.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int function(out RESOURCE_PARAMETERS parameters);

RESOURCE_PARAMETERS parameters;
int result = function(out parameters);

答案 2 :(得分:-1)

调用此函数的另一种非常简单的方法是:

Create a c++ dll warapper that link your original dll and contains this function

//c++ code

function2(uint param1, uint param2.....)
{
  RefPar refpar;

  refpar.param1=param1

  refpar.param2=param2

  function(&refpar)

}



in this way you have just to import (in C#) the dll wrapper function in this way


[DllImport("wrapperdll.dll", EntryPoint = "function2"]
static extern int function2(Uint32 param1,Uint32 param2....);


that is very simple to call.


Regards