Я пытаюсь передать указатель класса из родной DLL в CLR. Я не настолько успешна в этом. Я добираюсь до точки, в которой он возвращает указатель, используя void *, а затем преобразовывая его в ClassType * с помощью IntrPtr и ToPointer(). Но в тот момент, когда я пытаюсь получить доступ к его методам-членам, он не может получить старые значения свойств. Вместо этого я получаю 0 и некоторые случайные значения.Можно ли передавать указатели объектов между CLR и родным C++?
Я даже пытался использовать VC100 в качестве набора инструментов для CLR и native dll. Тем не менее я получаю значение «Ошибка чтения символов строки».
Я пытался использовать Google и не могу найти много информации о передаче указателей объектов из native в CLR. Я упомянул даже о step-by-step, доступном в проекте кода.
Edited добавить это:
У меня есть DLL родной, где функция, которая возвращает указатель на объект
Native.dll:
#if defined EXPORTDLL // inside DLL
#define DLL_EXPORT __declspec(dllexport)
#else // outside DLL
#define DLL_EXPORT __declspec(dllimport)
#endif
.....
DLL_EXPORT void* SomeMethod(uint16_t num1, const char * str1, const char * str2)
{
Obj1 obj(...);
...
return (void*)&obj; // <- at this point it is still correct
}
....
class DLL_EXPORT Obj1{
....
const std::string var1;
const std::string var2;
const std::string var3;
....
DLL_EXPORT strct1 memberFunction1()
{
// do something with the variables
// here when its called by managed code, the var1, var2, var3 shows random values and bad ptr..
}
...
}
, а затем в управляемый код CLR I вызовите memberFunct1 с помощью указателя возврата.
[DllImport("Native.dll", EntryPoint = "[email protected]@[email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]", CallingConvention = CallingConvention::Cdecl)]
IntPtr * SomeMethod(uint16_t num1, [In, MarshalAs(UnmanagedType::LPStr)]String^ str1, [In, MarshalAs(UnmanagedType::LPStr)] String^ str2);
.....
String^ str1 = gcnew String("1223568");
String^ str2 = gcnew String("1.2.3.5");
Obj1 *objptr = (Obj1*)(SomeMethod(1,str1, str2)).ToPointer();
// <- at this point the objptr properties are showing garbage
objptr->memberFunction1();
Я использую этот obj1 указатель для вызова метода члена, но в методе члена значения членов показывают, как плохо PTR.
Может кто-нибудь указать мне в правильном направлении, пожалуйста?
Заранее спасибо.
Я добавил дополнительный метод в свою родную dll.
void DLL_EXPORT SomeMethod2(int i1, const char* var1, const char* var2, Obj1* retval);
И назвал его из моего CLR проекта
[DllImport("Native.dll", EntryPoint = "[email protected]@[email protected]@@Z", CallingConvention = CallingConvention::Cdecl)]
void SomeMethod2(int i1, [MarshalAs(UnmanagedType::LPStr)]String^ var1, [MarshalAs(UnmanagedType::LPStr)]String^ var2, Obj1* retval);
....
Obj1 * testPtr3;
SomeMethod2(1, (char*)(void*)Marshal::StringToHGlobalAnsi(str1), (char*)(void*)Marshal::StringToHGlobalAnsi(str2), testPtr3);
SomeMethod2(1, str1, str2, testPtr3);
Obj1 testPtr2 = Obj1(1, (char*)(void*)Marshal::StringToHGlobalAnsi(str1), (char*)(void*)Marshal::StringToHGlobalAnsi(str2));
Но я получаю ошибки ссылку? Я уже связал это ?? !! ??
ошибка LNK2028: неразрешенный токен (0A000356) "public: __thiscall Obj1 :: Obj1 (int, char const *, char const *)" (?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z), на который ссылается функция " int __cdecl main (void) "(? main @@ $$ HYAHXZ)
ошибка LNK2028: неразрешенный токен (0A00035B)" void __cdecl SomeMethod2 (int, char const *, char const *, class Obj1 *) "(? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z) ссылка в функции "INT __cdecl основной (ничтожной)" (главный @@ $$ HYAHXZ)
ошибка LNK2019: неразрешенный внешний символ «общественность: __thiscall Obj1 :: Obj1 (int, char const *, char const *) "(?? 0Obj1 @@ $$ FQAE @ HPBD0 @ Z), на который ссылается функция" int __cdecl main (void) "(? main @@ $$ HYAHXZ)
ошибка LNK2019: неразрешенный внешний символ "void __cdecl SomeMethod2 (int, char const *, char const *, класс Obj1 *)" (? SomeMethod2 @@ $$ FYAXHPBD0PAVObj1 @@@ Z), на который ссылается функция "int __cdecl main (void) "(?Основной @@ $$ HYAHXZ)
@Martin Извините, я редактировал свое сообщение и добавил некоторые коды. – ras
Это стандартное болото [ошибка оборванного указателя] (https://en.wikipedia.org/wiki/Dangling_pointer). Очень распространенная ошибка в программе на C или C++, обычно очень сложная для диагностики. Но не тогда, когда вы используете pinvoke, пространство стека, требуемое маршеллером pinvoke, гарантирует, что 'obj' будет перезаписано надежно. Вы должны сохранить его в другом месте, лучшее место почти всегда является стекю стека вызывающего. Измените тип возврата на void и добавьте параметр 'Obj1 * retval'. –
@ HansPassant Я тоже попробовал. Но я все еще получаю сообщение об ошибке. Я редактировал свой пост, чтобы включить то, что вы упомянули, и добавил изображение, показывающее ссылку. – ras