2013-03-01 73 views
1

我遇到以下問題。 我使用以下函數從緩衝區接收字符串,直到出現換行符。C++ Dll字符串函數崩潰

string get_all_buf(int sock) { 
    int n = 1, total = 0, found = 0; 
    char c; 
    char temp[1024*1024]; 
    string antw = ""; 

    while (!found) { 
     n = recv(sock, &temp[total], sizeof(temp) - total - 1, 0); 
     if (n == -1) { 

      break; 
     } 
     total += n; 
     temp[total] = '\0'; 
     found = (strchr(temp, '\n') != 0); 

     if (found == 0){ 
     found = (strchr(temp, '\r\n') != 0); 
     } 
    } 
    antw = temp; 

    size_t foundIndex = antw.find("\r\n"); 
    if (foundIndex != antw.npos) 
    antw.erase (antw.find ("\r\n"), 2); 

    foundIndex = antw.find("\n"); 
    if (foundIndex != antw.npos) 
    antw.erase (antw.find ("\n"), 2); 

    return answ; 
} 

因此,使用這樣的:

string an = get_all_buf(sClient); 

如果我創建一個EXE文件的一切完美的作品。 但是,如果我創建了一個DLL和使用RUNDLL32應用程序關閉在「string an = get_all_buf(sClient);」沒有任何錯誤信息運行...

我想現在就解決這個問題了幾個小時,我現在有點絕望...

PS對於明顯的錯誤或錯誤的編碼風格感到抱歉,我剛開始學習C++。

+0

你爲什麼要用rundll32.exe來運行它?除此之外你還沒有任何環境,不是嗎?在VS中構建一個C++項目並鏈接到您的DLL。 – 2013-03-01 10:54:33

+0

你還可以包含你從rundll32的命令行運行的* proc *,它最終會調用它嗎?這可能很重要。除此之外,請參閱simon的答案,因爲您的猜測與我的rundll32用於默認堆棧大小(可能恰好爲1MB,因此您應該dyna-分配該臨時緩衝區)一樣好。 – WhozCraig 2013-03-01 10:57:26

回答

3
char temp[1024*1024]; 

在棧上聲明1Mb結構。這可能太大並且溢出可用的堆棧內存。你可以不是給它的靜態範圍

static char temp[1024*1024]; 

或動態分配或者它

char* temp = (char*)malloc(1024*1024); 
// function body 
free(temp); 

,假設run32.dll的提及意味着你在Windows上工作,你可以調查保持它在堆棧上通過使用/STACK鏈接器選項。這可能不是最好的方法 - 當您更改構建設置或嘗試定位其他平臺時,您已經發現它會導致問題。

+0

哇!有效! char temp [1024 * 1024];完美工作 非常感謝你! :D 這樣一個簡單的解決方案,我有幾個小時的麻煩^^ – incognym 2013-03-01 11:04:24

1

而是在棧上創建temp可變的,我會動態地創建它(在堆上),而不是使用原始mallocfree如在前面的回答顯示出,但用現代C++和std::vector

#include <vector> 

std::vector<char> temp(1024*1024); 

這是異常安全,而你沒有注意釋放分配的內存:std::vector的析構函數會做自動(也異常的情況下,拋出)。

相反的sizeof(temp),在你的代碼,你可以使用temp.size()(這將返回元素的個數的向量,因爲這是char個向量,它會在char小號即只返回總矢量大小字節)。

對於std::vector,您仍然可以使用operator[],就像您對原始C數組所做的一樣。

還要注意的是,如果你正在建設一個DLL和上面的函數在DLL接口暴露出來,因爲這個功能與在邊界一個STL類(std::string)一C++接口,你一定要注意這兩個DLL您和您的客戶都建有動態鏈接同CRT,並與相同的編譯器相同的編譯器設置(例如,你不能混用與VS2008/VC9內置一個DLL一個 。用VS2010/VC10構建的EXE,或者帶有使用相同編譯器構建的調試構建EXE的發佈構建DLL)。