111,098
社区成员




#ifndef RANDOMTEST_H
#define RANDOMTEST_H
#define FREQUENCY 1
#define EXPORT_API __declspec(dllexport)
_declspec(dllexport) int RandomTest(int testid, int m, int bitlen,BitSequence *epsilon,int testserial,double *pvalue);
#endif
typedef unsigned char BitSequence;
说白了就是一个8bit的无符号整形的指针,pvalue是double型的指针,但关键是这两个指针指向的内容会在dll中进行修改(C#申请空间--〉传指针到dll中--〉dll修改--〉C#再读出指针指向的内容)public static class DLLWrapper
{
///<summary>
/// API LoadLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);
///<summary>
/// API GetProcAddress
///</summary>
[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle, String funcname);
///<summary>
/// API FreeLibrary
///</summary>
[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);
///<summary>
///通过非托管函数名转换为对应的委托
///</summary>
///<param name="dllModule">通过LoadLibrary获得的DLL句柄</param>
///<param name="functionName">非托管函数名</param>
///<param name="t">对应的委托类型</param>
///<returns>委托实例,可强制转换为适当的委托类型</returns>
public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
{
int address = GetProcAddress(dllModule, functionName);
if (address == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
}
///<summary>
///将表示函数地址的IntPtr实例转换成对应的委托
///</summary>
public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
{
if (address == IntPtr.Zero)
return null;
else
return Marshal.GetDelegateForFunctionPointer(address, t);
}
///<summary>
///将表示函数地址的int转换成对应的委托
///</summary>
public static Delegate GetDelegateFromIntPtr(int address, Type t)
{
if (address == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
}
}
delegate int COUNT(int a, int b, int c, IntPtr d, int e, IntPtr f);
string funname = "RandomTest";
int launchresult;
int hModule = DLLWrapper.LoadLibrary(dllfilepath);
if (hModule == 0)
{
MessageBox.Show("组件加载失败");
}
else
{
COUNT launchdll = (COUNT)DLLWrapper.GetFunctionAddress(hModule, funname, typeof(COUNT));
if (launchdll == null)
{
DLLWrapper.FreeLibrary(hModule);
MessageBox.Show("组件运行失败");
}
else
{
int a0 = 1;
int b0 = 1;
int c0 = 1;
//byte d0 = 0xF1;
int e0 = 1;
double f0 = 0.5;
IntPtr ptrbyte = Marshal.AllocHGlobal(sizeof(byte));//申请byte非托管内存
Marshal.WriteByte(ptrbyte, 0xF1);
IntPtr ptrdouble = Marshal.AllocHGlobal(sizeof(double));//申请double非托管内存
launchresult = launchdll(a0, b0, c0, ptrbyte, e0, ptrdouble);
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int COUNT(int a, int b, int c, ref byte d, int e, ref double f);
用UnmanagedFunctionPointer特性修饰你的函数声明。UnmanagedFunctionPointer可见http://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.unmanagedfunctionpointerattribute%28v=vs.80%29.aspxint RandomTest(int testid, int m, int n,BitSequence *epsilon,int testserial,double *pvalue)
{
int ret;
switch (testid)
{
case 1:
ret=Frequency(n,epsilon,testserial,pvalue);
break;
default:
ret=-1;
break;
}
return ret;
}
相关的Frequency函数就是这个功能
int Frequency(int n,BitSequence *epsilon,int testserial,double *pvalue)
{
n=100;
*pvalue=0.05;
*epsilon=0xff;
return 56;
}
是不是我调用DLL时指针没声明好?