2016-07-09 16 views
-1

我很迷失這個C++錯誤。exe和dll之間的C++調用錯誤

我有一個「exe」,它導出「.lib」,並加載一個導入這個「.lib」的「dll」。我可以用這個方法解決問題。但是當我使用「EscapeJson」時,會出現異常。如果我將代碼複製到庫中,並用「EscapeJson」(同一個庫)替換「CoreHelper :: EscapeJson」,那麼所有這些都是正確的...

有什麼不對?

My.EXE (Export) -> My.lib (Import) -> MyDll.dll 
^         | 
    `--------------------------------------- 

Error

同樣的代碼工作,因爲 「EscapeJson」 成功返回值...

But code works

逃生JSON原始碼

std::string CoreHelper::EscapeJson(char * input, int length) 
{ 
    std::ostringstream o; 
    for (int x = 0; x < length; x++) 
    { 
     char c = input[x]; 
     switch (c) 
     { 
     case '"': o << "\\\""; break; 
     case '\\': o << "\\\\"; break; 
     case '\b': o << "\\b"; break; 
     case '\f': o << "\\f"; break; 
     case '\n': o << "\\n"; break; 
     case '\r': o << "\\r"; break; 
     case '\t': o << "\\t"; break; 
     default: 
      if ('\x00' <= c && c <= '\x1f') 
      { 
       o << "\\u" 
        << std::hex << std::setw(4) << std::setfill('0') << (int)c; 
      } 
      else 
      { 
       o << c; 
      } 
     } 
    } 
    return o.str(); 
} 

回答

1

您無法跨越DLL邊界傳遞std::string(或幾乎任何其他非POD類型)。在這種情況下,std::string的原始內存分配在EXE內部,並由編譯到EXE中的內存管理器進行管理。該DLL將無法正確釋放它,只有EXE可以。

您需要使用跨DLL邊界安全使用的互操作安全數據類型和內存管理技術。

在這種情況下,嘗試更多的東西像這個:

char* CoreHelper::EscapeJson(char * input, int length) 
{ 
    std::ostringstream o; 
    //... 
    std::string s = o.str(); 
    char *res = new char[s.size()+1]; 
    std::copy(s.begin(), s.end(), res); 
    res[s.size()] = 0; 
    return res; 
} 

void CoreHelper::FreeEscapedJson(char * input) 
{ 
    delete [] input; 
} 

char *str = CoreHelper::EscapeJson(...); 
// use str as needed... 
CoreHelper::FreeEscapedJson(str); 
+0

你救我的生命!謝謝! –