我在c ++ DLL中有一个具有以下原型的函数
int function(RefPar ¶ms);
如何使用“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个枚举 价值作为其成员。
请任何人帮我正确调用该功能..
答案 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 ¶meters)
{
}
<强> 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