2012-04-25 41 views
1

私はC++ Win32のプログラムを作成しています。このプログラムでは、テキストファイルを作成しています。このC++プログラムはDLLを生成し、ASP.NET WebアプリケーションでこのDLLを参照しています。
P/Invokeを使用して、このDLLからファイルを読み書きするメソッドを呼び出しています。ASP.NETでのP/Invoke(dllからのテキストファイルの読み込み/書き込み)

私はこれをWP /アプリケーションでWPFアプリケーションでテストしたところ、dllはうまく動作しています。 リファレンスDLLはこのWPFアプリケーションのbin/Debugフォルダにあり、呼び出されるとdllの書き込みメソッドは同じフォルダにテキストファイルを生成します。 さらに、from the same folder、私はテキストファイルを読むためにdllのreadメソッドを使うことができます。

しかし、私がASP.NET WebアプリケーションからDllメソッドを呼び出すと、遺伝子操作されたファイルは他のディレクトリに移動します(おそらく、dllは実行のために他の場所にロードされているためです) (エラーなし)

デスクトップアプリケーションと同じように、binフォルダー自体から読み込むことができるように、binフォルダー自体にfieが書き込まれる方法はありますか?

例コード:
.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

..andは、デフォルトの作業ディレクトリを使用した場合も、アクセス許可の問題を持つことができます - 例えばIISプロセスが書き込めないディレクトリで終わる可能性があります。 – MiMo

+0

@MMo真実ですが、あなたがファイルを望む場所ではないという事実は、本当にキラーです。 –

+0

確かに - 現在の作業ディレクトリを使いこなすのが最善である理由をもう一つ追加したところです。 – MiMo

関連する問題