1

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

WPFアプリケーションでP/invokeを使用してこれをテストしたところ、dllは正常に機能しています。参照dllはbin/DebugこのWPFアプリのフォルダーにあり、dllのwriteメソッドが呼び出されると、同じフォルダーにテキストファイルが生成されます。さらに、from the same folderdllのreadメソッドを使用してテキストファイルを読み取ることができます。

ただし、ASP.NET WebアプリからDllメソッドを呼び出すと、生成されたファイルは別のディレクトリに移動し(おそらく、実行のためにdllが別の場所にロードされているため)、この生成されたファイルの移動先を見つけることができません(エラーなし)

デスクトップアプリケーションと同様に、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();
4

1 に答える 1

2

相対パスを使用しているため、ファイルは、ネイティブコードを呼び出した時点でのプロセスの作業ディレクトリからの相対パスになります。あなたが発見したように、これはかなりもろい配置です。

使用するファイルのフルパスを指定する追加の文字列パラメーターをネイティブコードに追加することで、問題を解決します。これは、マネージコードから簡単に生成できます。

ネイティブコード

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

マネージコード

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

もう1つのポイントは、データを読み取る関数が正しくないことです。スタックに割り当てられたバッファを返そうとします。マネージコードにバッファを割り当ててから、それをネイティブコードに渡す必要があります。おそらくこのようなもの:

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);
于 2012-04-25T11:05:24.817 に答える