Я ищу гибкие способы написания своих собственных библиотек DLL и доступа к библиотекам DLL, которые обрабатываются для меня в C ++ с использованием C ++ / CLI. Я довольно новичок в InterOp и Reflection, и особенно мне кажется, что маршалинг StringBuilder в функцию DLL, которая принимает точку входа с параметром char * (helloc в коде), эффективен при использовании DefinePInvokeMethod. IJW заботится о случае, когда точка входа принимает std :: string при прямом вызове dll, но почему существуют TargetInvocationExceptions, когда я также пытаюсь маршалировать StringBuilder в std :: string, используя DefinePInvokeMethod. Почему средство IJW не знает, как создать std :: string в этом случае? Разве вызываемый не отвечает за построение строки на неуправляемой стороне? Ниже приведен рабочий код. Кто-нибудь, пожалуйста, помогите мне через его адаптацию так, чтобы hellos (std :: string) также был доступен через DefinePInvokeMethod?
native.dll
//Both methods just std::cout << greeting;
extern "C" DLL void helloc(char* greeting);
extern "C" DLL void hellos(std::string greeting)
test.cpp
void pinvoketest()
{
// Create the AssemblyBuilder.
AssemblyName^ asmName = gcnew AssemblyName("PInvokeTest");
AssemblyBuilder^ dynamicAsm = AppDomain::CurrentDomain->DefineDynamicAssembly(
asmName,
AssemblyBuilderAccess::RunAndSave
);
// Create the module.
ModuleBuilder^ dynamicMod =
dynamicAsm->DefineDynamicModule(asmName->Name, asmName->Name + ".dll");
TypeBuilder^ tb = dynamicMod->DefineType(
"MyType",
TypeAttributes::Public | TypeAttributes::UnicodeClass
);
MethodInfo^ mi;
try
{
MethodBuilder^ mb = tb->DefinePInvokeMethod(
"helloc",
"native.dll",
"helloc",
MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
CallingConventions::Standard,
void::typeid,
gcnew array<Type^>{StringBuilder::typeid},
CallingConvention::Cdecl,
CharSet::Ansi);
mb->SetImplementationFlags(
mb->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);Type^ t = tb->CreateType();mi = t->GetMethod("helloc");
Console::WriteLine("Testing PInvoke method...");
mi->Invoke(nullptr, gcnew array<Object^>{gcnew StringBuilder("This is a test greeting")});
char x;
std::cin >> x;
}
catch (TargetInvocationException^ ex)
{
Console::WriteLine(ex->InnerException);
char x;
std::cin >> x;
}
catch (Exception^ ex)
{
Console::WriteLine(ex);
char x;
std::cin >> x;
}
};
Задача ещё не решена.
Других решений пока нет …