.net 对本机库的动态调用
我尝试从原生C++ DLL调用函数,由名称、参数和返回类型给出。 现在,我有问题,使代表编组 我正在这样做:.net 对本机库的动态调用,.net,visual-studio,c++-cli,.net,Visual Studio,C++ Cli,我尝试从原生C++ DLL调用函数,由名称、参数和返回类型给出。 现在,我有问题,使代表编组 我正在这样做: Object^ Invike(Type^ Return_Type, array<Type^>^ Types, array<Object^>^ Parameters) { //demo data Return_Type=long::typeid; Types = gcnew array < Type^ > {String::typeid, int:
Object^ Invike(Type^ Return_Type, array<Type^>^ Types, array<Object^>^ Parameters)
{
//demo data
Return_Type=long::typeid;
Types = gcnew array < Type^ > {String::typeid, int::typeid};
Parameters = gcnew array < Type^ > {"test",1};
//parameters initializated in class constructor
//IntPtr DLL_File = Native_Dll::LoadLibrary(Dll_Name);
//IntPtr Init_Function = Native_Dll::GetProcAddress(DLL_File, "_McamGetNumberofCameras@0");
DynamicMethod^ Function_Prototype = gcnew DynamicMethod("test", Return_Type, Types);
//ArgumentException exception in this line
Delegate^ Function_Delegate = Marshal::GetDelegateForFunctionPointer(Init_Function, Function_Prototype->GetType());
Object^ Result = Function_Delegate->DynamicInvoke(Parameters);
return Result;
}
有可能做我想做的事吗
还有其他方法吗
我也在寻找Func模板,但并不真正了解如何使用它。我确实通过使用AssemblyBuilder制作动态包装解决了这个问题。 这是代码段
AssemblyName^ Delegate_Class_Name = gcnew AssemblyName("Dynamic_Class");
AssemblyBuilder^ Delegate_Class = AppDomain::CurrentDomain->DefineDynamicAssembly(Delegate_Class_Name, AssemblyBuilderAccess::RunAndSave);
ModuleBuilder^ Delegate_Class_Module = Delegate_Class->DefineDynamicModule(Delegate_Class_Name->Name, Delegate_Class_Name->Name + ".dll");
TypeBuilder^ Delegate_Class_Type = Delegate_Class_Module->DefineType("Dynamic_Class_Type", TypeAttributes::Public);
//a can add as much functions from native dll as a need
MethodBuilder^ Delegate_Function = Delegate_Class_Type->DefinePInvokeMethod(
"_McamGetNumberofCameras@0",
Dll_Name,
MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
CallingConventions::Standard,
long::typeid,
Type::EmptyTypes,
CallingConvention::Winapi,
CharSet::Ansi);
Delegate_Function->SetImplementationFlags(Delegate_Function->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);
Type^ Delegate_Type = Delegate_Class_Type->CreateType();
MethodInfo^ Delegate_Instace = Delegate_Type->GetMethod("_McamGetNumberofCameras@0");
//now i can just run it.
int result= (int) Delegate_Instace->Invoke(nullptr, nullptr);
这是不可能的,GetDelegateForFunctionPointer()不支持泛型委托。您必须显式声明委托类型。那当然很痛苦。只要您使用LoadLibrary+GetProcAddress,最好使用[DllImport]来声明导出的函数。pinvoke marshaller免费为您提供一切,包括您试图编写的DynamicMethod管道。@Hans Passant说的“pinvoke marshaller”是指[DllImport]?就像这里的[DllImport(“kernel32.dll”)]静态IntPtr加载库(字符串^dll\u名称);我可以直接在代码中使用LoadLibrary(“名称”)。
AssemblyName^ Delegate_Class_Name = gcnew AssemblyName("Dynamic_Class");
AssemblyBuilder^ Delegate_Class = AppDomain::CurrentDomain->DefineDynamicAssembly(Delegate_Class_Name, AssemblyBuilderAccess::RunAndSave);
ModuleBuilder^ Delegate_Class_Module = Delegate_Class->DefineDynamicModule(Delegate_Class_Name->Name, Delegate_Class_Name->Name + ".dll");
TypeBuilder^ Delegate_Class_Type = Delegate_Class_Module->DefineType("Dynamic_Class_Type", TypeAttributes::Public);
//a can add as much functions from native dll as a need
MethodBuilder^ Delegate_Function = Delegate_Class_Type->DefinePInvokeMethod(
"_McamGetNumberofCameras@0",
Dll_Name,
MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
CallingConventions::Standard,
long::typeid,
Type::EmptyTypes,
CallingConvention::Winapi,
CharSet::Ansi);
Delegate_Function->SetImplementationFlags(Delegate_Function->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);
Type^ Delegate_Type = Delegate_Class_Type->CreateType();
MethodInfo^ Delegate_Instace = Delegate_Type->GetMethod("_McamGetNumberofCameras@0");
//now i can just run it.
int result= (int) Delegate_Instace->Invoke(nullptr, nullptr);