C# 调用C++ dll 方法返回char* 乱码
2013-09-26 10:57
591 查看
直接上代码
DllImporter.cs 代码如下
C++ 代码中 #define MEDUSA_EXPORT_API __declspec(dllexport) static char[1024*2] buff;//使用静态数组返回才不会乱码,即使在调用方法中使用堆内存也会被释放,所以声明全局静态编辑 MEDUSA_EXPORT_API char* getChar() { std::string a = "hello"; strcpy(buff,a.c_str()); return buff; }
C# 代码中 public delegate InPtr getChar();//使用动态指针做返回值 private readonly DllImporter mDll = new DllImporter(); public void runDll() { string dllpath = "xxxx.dll"; mDll.Open(dllpath); InPtr p = mDll.Invoke<getChar,InPtr>(); string str = Marshal.PtrToStringAnsi(p); }
DllImporter.cs 代码如下
namespace MedusaSimulator { class DllImporter { [DllImport("kernel32.dll")] public static extern IntPtr LoadLibrary(string path); [DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr lib, string funcName); [DllImport("kernel32.dll")] public static extern bool FreeLibrary(IntPtr lib); private IntPtr mDll = IntPtr.Zero; public bool IsLoaded { get { return mDll != IntPtr.Zero; } } public DllImporter() { } public void Open(string path) { if (mDll == IntPtr.Zero) { mDll = LoadLibrary(path); } } public void Close() { if (mDll != IntPtr.Zero) { FreeLibrary(mDll); mDll = IntPtr.Zero; } } private readonly Dictionary<Type, MethodInfo> mMethods = new Dictionary<Type, MethodInfo>(); public T InvokeMethod<T>() where T : class { var methodType = typeof(T); var methodPtr = GetProcAddress(mDll, methodType.Name); var callback = Marshal.GetDelegateForFunctionPointer(methodPtr, methodType); return callback as T; } public TR Invoke<T, TR>(params object[] parameters) where T : class { var delegateType = typeof(T); if (mMethods.ContainsKey(delegateType)) { var methodInfo = mMethods[delegateType]; return (TR)methodInfo.Invoke(null, parameters); } var myAssemblyName = new AssemblyName { Name = "DllImporter" }; var myAssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run); var myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("DllImporter"); var delegateMethod = delegateType.GetMethod("Invoke"); var paramInfos = delegateMethod.GetParameters(); var paramTypes = paramInfos.Select(parameterInfo => parameterInfo.ParameterType).ToArray(); var methodPtr = GetProcAddress(mDll, delegateType.Name); var myMethodBuilder = myModuleBuilder.DefineGlobalMethod(delegateType.Name, MethodAttributes.Public | MethodAttributes.Static, delegateMethod.ReturnType, paramTypes); var il = myMethodBuilder.GetILGenerator(); for (var i = 0; i < paramInfos.Length; i++) { il.Emit(OpCodes.Ldarg, i); //by value //IL.Emit(OpCodes.Ldarga, i); //by ref } il.Emit(OpCodes.Ldc_I4, methodPtr.ToInt32()); il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, delegateMethod.ReturnType, paramTypes); il.Emit(OpCodes.Ret); myModuleBuilder.CreateGlobalFunctions(); var myMethodInfo = myModuleBuilder.GetMethod(delegateType.Name); mMethods[delegateType] = myMethodInfo; return (TR)myMethodInfo.Invoke(null, parameters); } } }
相关文章推荐
- c#调用c++写成的dll文件,返回char*,返回数组,用ref接收,byte[] (zz)
- C#调用C++dll方法,char*类型之间的传递
- c#调用c++写成的dll文件,返回char*,返回数组,用ref接收,byte[]
- c#调用c++写成的dll文件,返回char*,返回数组,用ref接收,byte[] (zz)
- C# 调用 C++ DLL无法调试的问题解决方法
- c#、C++等调用Dll方法(未完)
- C# 调用C++DLL传递的bool型,返回混乱
- C#反射动态调用dll中的方法,并返回结果[转]
- C#调用C++dll文件获取数据得到乱码的解决方法
- C#动态调用c++DLL的方法
- 浅谈C++调用C#的DLL程序方法
- C#调用C++方法,C#使用c++方法返回类或结构体
- Socket发送消息之c#调用c++DLL方法
- [总结]非托管C++代码调用C#编写的dll方法
- C#调用C++封装的DLL调试方法小结
- C#调用C++的dll时,c++ dll函数接口中尽量不要用bool返回类型
- C++调用C#的DLL实现方法
- C#调用C++ dll及dll编写方法
- C++调用C#的DLL实现方法
- C# 调用C++DLL参数异常解决方法