Передача std :: string из VC ++ 2005 в VC ++ 6 DLL приводит к мусору - PullRequest
0 голосов
/ 26 ноября 2009

У меня есть библиотека динамических ссылок, написанная на VC ++ 6. Я написал некоторый код для VC ++ 2005, который вызывает нативную библиотеку VC ++ 6. Всякий раз, когда я передаю std :: string в собственную библиотеку, результатом всегда является мусор. Однако этого не произойдет, если я передам другие типы, такие как char *, int и т. Д. Какой-нибудь идеал, что вызывает это?

Следующий код иллюстрирует это.

// VC ++ 6 Code

class __declspec(dllexport) VC6  
{  
      public:  
      VC6();  
      void DoSomething(const std::string &s);  
}  

VC6()::VC6() {}    

void VC6::DoSomething(const std::string &s)  
{  
       std::cout << s; // Resulting output on screen is garbage  
}  

// VC ++ 2005 Code

void VC2005::DoSomething()  
{      
      VC6 *vc6 = new VC6();

      std::string s("Test String");  
      vc6->DoSomething(s);  

      delete vc6;  
}  

Ответы [ 3 ]

3 голосов
/ 26 ноября 2009

Классы, такие как std :: string, не обязательно определяются одинаково в каждой версии библиотеки времени выполнения (даже если они имеют одинаковое имя), поэтому не следует смешивать библиотеки таким образом. С другой стороны, такие типы, как int и char * одинаковы для данной платформы, поэтому вы можете передавать их.

В вашем примере лучше передать строку в виде пары (указатель, размер) или просто в виде строки с нулевым символом в конце.

Edit: забыл упомянуть очевидное решение использования той же версии компилятора. Сделайте это, если хотите передать объекты.

0 голосов
/ 29 ноября 2009

Вы можете написать DLL-оболочку с интерфейсом C. Оболочка C ++ / CLI может понадобиться, если один p-invoke не может обработать взаимодействие. Написание COM-сервера в ATL, вероятно, является лучшим выбором для предоставления объектно-ориентированного интерфейса в нативном коде и во избежание написания другой библиотеки DLL-оболочки для C ++ / CLI).

0 голосов
/ 26 ноября 2009

Не делай этого. Это не работает.

C ++ не определяет фиксированный ABI, поэтому вы вообще не можете передавать не POD-типы между библиотеками или модулями перевода, скомпилированными различными компиляторами.

В вашем случае VC6 и VC8 имеют разные определения std::string (и компиляторы также могут вставлять разные дополнения и другие изменения), и в результате получается мусор, и / или непредсказуемое поведение и сбои.

Если вам нужно передать данные в библиотеку VC6 DLL (лучшим вариантом может быть перекомпиляция этого кода с помощью нормального компилятора), вы должны придерживаться типов, в которых вы можете быть уверены, что они будут работать. Это означает 1) типы POD (либо встроенные примитивы, такие как char*, либо структуры C, содержащие только типы POD), либо объекты COM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...