1

我有一个C++ Win32正在编写和读取文本文件的程序。这个 C++ 程序生成一个 dll,我在我的 ASP.NET Web 应用程序中引用了这个 dll。
使用 P/Invoke,我正在调用从该 dll 读取和写入文件的方法。

当我在 WPF 应用程序中使用 P/invoke 对其进行测试时,该 dll 工作正常。引用 dll 位于bin/Debug此 WPF 应用程序的文件夹中,调用 dll 中的 write 方法会在同一文件夹中生成一个文本文件。此外,from the same folder我可以使用 dll 的 read 方法来读取文本文件。

但是,当我从我的 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();
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();

另一点是您读取数据的功能不正确。它试图返回一个堆栈分配的缓冲区。您需要在托管代码中分配一个缓冲区,然后将其传递给本机代码。也许是这样的:

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 回答