2012-04-25 106 views
1

我有一個C++ Win32程序,我在其中編寫和閱讀文本文件。這個C++程序生成一個DLL,我在我的ASP.NET Web應用程序中引用這個DLL。
使用P/Invoke,我調用讀取和寫入該dll文件的方法。ASP.NET中的P/Invoke(從dll讀取/寫入文本文件)

當我用WPF應用程序中的P/invoke測試了這個DLL時,dll工作正常。 參考dll位於此WPF應用程序的bin/Debug文件夾中,並且在調用dll時,寫入方法在同一文件夾中生成文本文件。 此外,from the same folder,我可以使用dll的讀取方法來讀取文本文件。

但是,當我從我的ASP.NET Web應用程序調用Dll方法時,生成的文件會轉到其他目錄(很可能是因爲dll被加載到其他地方執行),我無法找到這個位置生成的文件去(沒有任何錯誤)

與桌面應用程序類似,是否有某種方式,fie將被寫入bin文件夾本身,以便我可以從bin文件夾本身讀取?

示例代碼:
cpp文件

extern "C" D_API int Write1() 
{ 
    ofstream myfile; 
    myfile.open ("example.txt"); 
    myfile << "Writing this to a file.\n"; 
    myfile.close(); 
    return 1; 
} 

extern "C" D_API char* Read1() 
{ 
    ifstream myReadFile; 
    myReadFile.open("test.txt"); 
    char output[100]; 
    if (myReadFile.is_open()) 
    { 
     while (!myReadFile.eof()) 
     { 
     myReadFile >> output;  
     } 
    } 
    return output; 
} 

C#.aspx.cs

[DllImport("Testing1.dll", EntryPoint = "fnTest", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
     public static extern int Write1(); 


     [DllImport("Testing1.dll", EntryPoint = "ReadTest", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
     public static extern StringBuilder Read1(); 

回答

2

由於使用相對路徑,該文件將是相對於工作您調用本機代碼時所在進程的目錄。這是你發現的一個相當脆弱的安排。

我會通過向指定要使用的文件的完整路徑的本機代碼添加額外的字符串參數來解決問題。我確信您可以從託管代碼中輕鬆生成此代碼。

本地代碼

extern "C" D_API int WriteTest(char *filename) 
{ 
    .... 
    myfile.open(filename); 
    .... 
} 

託管代碼

[DllImport("Testing1.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int WriteTest(); 

另一點要提出的是,你的函數讀取數據不正確。它試圖返回一個堆棧分配的緩衝區。您需要在託管代碼中分配一個緩衝區,然後將其傳遞給本機代碼。也許是這樣的:

extern "C" D_API int ReadTest(char *filename, char* buffer, int len) 
{ 
    //read no more than len characters from filename into buffer 
} 

而且在管理方面:

[DllImport("Testing1.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int ReadTest(string filename, StringBuilder buffer, int len); 
.... 
StringBuilder buffer = new StringBuilder(100); 
int retval = ReadTest(FullySpecifiedFileName, buffer, buffer.Capacity); 
+0

..和使用默認的工作目錄也可以有權限的問題 - 例如,你可以結束一個IIS進程無法寫入的目錄。 – MiMo 2012-04-25 11:10:11

+0

@MMo的確如此,但事實並非你想要的文件是真正的殺手。 – 2012-04-25 11:14:09

+0

當然 - 我只是增加了一個理由,爲什麼最好避免使用當前工作目錄。 – MiMo 2012-04-25 11:17:23