using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Text;

namespace TEDS_App
{
public enum ModePass
{
ByValue = 0x0001,
ByRef = 0x0002
}
public class FaultFunc
{
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll")]
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32", EntryPoint = "FreeLibrary", SetLastError = true)]
static extern bool FreeLibrary(IntPtr hModule);
private IntPtr hModule = IntPtr.Zero;
private IntPtr farProc = IntPtr.Zero;
public void LoadDll(string lpFileName)
{
hModule = LoadLibrary(lpFileName);
if (hModule == IntPtr.Zero)
{
throw (new Exception("没有找到:" + lpFileName + "."));
}
}
public void LoadDll(IntPtr HMODULE)
{
if (HMODULE == IntPtr.Zero)
{
throw (new Exception("所传入的函数库模块的句柄为空"));
}
hModule = HMODULE;
}
public void LoadFun(string lpProcName)
{
if (hModule == IntPtr.Zero)
{
throw (new Exception("函数库模块的句柄为空,确保已进行加载dll操作"));
}
farProc = GetProcAddress(hModule, lpProcName);
if (farProc == IntPtr.Zero)
{
throw (new Exception("没有找到:" + lpProcName + "这个函数的入口点"));
}
}
public void LoadFun(string lpFileName, string lpProcName)
{
hModule = LoadLibrary(lpFileName);
if (hModule == IntPtr.Zero)
{
throw (new Exception("没有找到:" + lpFileName + "."));
}
farProc = GetProcAddress(hModule, lpFileName);
if (farProc == IntPtr.Zero)
{
throw (new Exception("没有找到:" + lpProcName + "这个函数的入口点"));
}
}
public void UnLoadDll()
{
FreeLibrary(hModule);
hModule = IntPtr.Zero;
farProc = IntPtr.Zero;
}
public object Invoke(object[] ObjArray_Parameter, Type[] TypeArray_parameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)
{
if (hModule == IntPtr.Zero)
throw (new Exception("函数库模块的句柄为空,请确保进行了LoadLll操作"));
if (farProc == IntPtr.Zero)
throw (new Exception("函数指针为空,请确保已进行LoadFun操作"));
if (ObjArray_Parameter.Length != ModePassArray_Parameter.Length)
throw (new Exception("参数个数及其传递方式的个数不匹配"));
AssemblyName MyAssemblyName = new AssemblyName();
MyAssemblyName.Name = "InvokeFun";
AssemblyBuilder MyAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(MyAssemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder MyModuleBuilder = MyAssemblyBuilder.DefineDynamicModule("InvokeDll");
MethodBuilder MyMethodBuilder = MyModuleBuilder.DefineGlobalMethod("FaultFun", MethodAttributes.Public | MethodAttributes.Static, Type_Return, TypeArray_parameterType);
ILGenerator IL = MyMethodBuilder.GetILGenerator();
int i;
for (i = 0; i < ObjArray_Parameter.Length; i++)
{
switch (ModePassArray_Parameter[i])
{
case ModePass.ByValue:
IL.Emit(OpCodes.Ldarg, i);
break;
case ModePass.ByRef:
IL.Emit(OpCodes.Ldarga, i);
break;
default:
throw (new Exception("第" + (i + 1).ToString() + "个参数没有给定正确的传递方式"));
}
}
if (IntPtr.Size == 4)
{
IL.Emit(OpCodes.Ldc_I4, farProc.ToInt32());
}
else if (IntPtr.Size == 8)
{
IL.Emit(OpCodes.Ldc_I8, farProc.ToInt64());
}
else
{
throw new PlatformNotSupportedException();
}
IL.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, Type_Return, TypeArray_parameterType);
IL.Emit(OpCodes.Ret);
MyModuleBuilder.CreateGlobalFunctions();
MethodInfo MyMethodInfo = MyModuleBuilder.GetMethod("FaultFun");
return MyMethodInfo.Invoke(null, ObjArray_Parameter);
}
public object Invoke(IntPtr IntPtr_Function, object[] ObjArray_Parameter, Type[] TypeArray_ParameterType, ModePass[] ModePassArray_Parameter, Type Type_Return)
{
if (hModule == IntPtr.Zero)
throw (new Exception("函数库模块的句柄为空,请确保已进行LoadDll操作"));
if (IntPtr_Function == IntPtr.Zero)
throw (new Exception("函数指针IntPtr_Function为空"));
farProc = IntPtr_Function;
return Invoke(ObjArray_Parameter, TypeArray_ParameterType, ModePassArray_Parameter, Type_Return);
}
}

}

 

调用方式如下:

PlusFunction.LoadDll(@"C:\win32dll.dll");//PlusFunction为调用类的实例
PlusFunction.LoadFun("MyFun");
byte[] a = File.ReadAllBytes(@"E:\19-bw\19-73.jpg");
object[] Parameters = new object[] {a}; // 实参为a
Type[] ParameterTypes = new Type[] { typeof(byte[])}; // 实参类型为byte[]
ModePass[] themode = new ModePass[] {ModePass.ByValue}; // 传送方式为值传
Type Type_Return = typeof(int); // 返回类型为int
ret = (int)PlusFunction.Invoke(Parameters, ParameterTypes, themode, Type_Return);

 

其实,c++与c#主要的就是数据类型的对应了。简单点的还好说,稍微复杂的各种麻烦。。。关键是不好调试。

 

c++ c#
char* char[](string.tochararray)
byte* byte[]
int int
int* int[]
结构体
c++
typedef struct SRectChange_TAG
{
//NV_RECT rect;
int x;//左上角x轴坐标
int y;//左上角y轴坐标
int width;//宽
int height;//高
int degree;//报错级别;1最低,目前暂时设定3级
}
SRectChange;
c#
[StructLayout(LayoutKind.Sequential)]
public struct SRectChange
{
public int x;
public int y;
public int width;
public int height;
public int degree;
}
结构体传递
[DllImport("win32dll.dll", EntryPoint = "MyFun", CallingConvention = CallingConvention.Cdecl)]
public static extern int MyFun(ref SRectChange rect, char[] str, char[] str2);
c++结构体
typedef struct
{
int osVersion;
int majorVersion;
int minorVersion;
int buildNum;
int platFormId;
char szVersion[128];
}OSINFO;
c#
// OSINFO定义
[StructLayout(LayoutKind.Sequential)]
public struct OSINFO
{
public int osVersion;
public int majorVersion;
public int minorVersion;
public int buildNum;
public int platFormId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string szVersion;
}

结构体数组传递
c#代码
[DllImport("win32dll.dll", EntryPoint = "MyFun", CallingConvention = CallingConvention.Cdecl)]
public static extern int MyFun(IntPtr p, char[] str, char[] str2);
数组传指针
char[] newpic = ("123123123123").ToCharArray();
char[] oldpic = ("231231234123").ToCharArray();
SRectChange[] rects = new SRectChange[5];
for (int i = 0; i < rects.Length; i++)
{
rects[i] = new SRectChange();
}
IntPtr[] ptArr = new IntPtr[1];
ptArr[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SRectChange)) * 5); //分配包含两个元素的数组
IntPtr pt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SRectChange)));
Marshal.Copy(ptArr, 0, pt, 1); //拷贝指针数组
MyFun(pt, newpic, oldpic);
for (int i = 0; i < 5; i++)
{
rects[i] = (SRectChange)Marshal.PtrToStructure((IntPtr)(pt.ToInt32() + i * Marshal.SizeOf(typeof(SRectChange))), typeof(SRectChange));
Console.WriteLine("x:{0} y:{1}", rects[i].x, rects[i].y);
}

 

posted on 2017-11-21 16:31  田坤坤  阅读(297)  评论(0编辑  收藏  举报