【问题标题】:Problems with Delphi DLL IStream parameter calling from C++从 C++ 调用 Delphi DLL IStream 参数的问题
【发布时间】:2019-04-28 20:16:40
【问题描述】:

我在 Delphi 上编写了 DLL。我只有没有头文件的 DLL,所以我动态加载它。 (到 C++ 项目)

HMODULE hLib = LoadLibrary(L"LibName.dll");
if (!hLib) {
//Throw error
}

DLL 提供功能:

function DataToFile(AddressName: PChar; Request: PChar;
  RequestSize: integer; ResultFile: PChar;
  ErrorBuf: PChar; ErrorBufSize: integer):BOOL;stdcall;

function DataToStream(AddressName: PChar; Request: PChar;
  RequestSize: integer; ResultStream: IStream;
  ErrorBuf: PChar; ErrorBufSize: integer):BOOL;stdcall;

我的 Visual Studio 代码(C++):

typedef bool(__stdcall* f_DataToFile)(
    char*,  //AddressName: PChar
    char*,  //Request: PChar
    int,    //RequestSize: integer
    char*,  //FileName: PChar
    char*,  //ErrorBuf: PChar
    int);   //ErrorBufSize: integer);

typedef bool(__stdcall* f_DataToStream)(
    char*,  //AddressName: PChar
    char*,  //Request: PChar
    int,    //RequestSize: integer
    std::istream &, //ResultStream: IStream
    char*,  //ErrorBuf: PChar
    int);   //ErrorBufSize: integer);

... 获得功能。地址:

//load DataToFile
f_DataToFile DataToFile = (f_DataToFile) GetProcAddress(hLib, "DataToFile");
if (!DataToFile) { //throw error 
}

//load DataToStream
f_DataToStream DataToStream = (f_DataToStream) GetProcAddress(hLib, "DataToStream");
if (!DataToStream) { //throw error
}

... 设置数据:

char* AddressName = _strdup("127.0.0.1:1234");  //AddressName: PChar
char* Request = _strdup("<?xml request... >");  //Request: PChar
int RequestSize = strlen(Request);  //RequestSize: integer

char* ResultFile = _strdup("exportpath\\output.xml");  //FileName: PChar
char* ErrorBuf = new char[255]; //ErrorBuf: PChar
int ErrorBufSize = 255;  //ErrorBufSize: integer);

std::filebuf(buffer);
std::istream ResultStream(&buffer);

... 第一个功能正常工作

bool reesult1= (DataToFile)(AddressName, Request, RequestSize, ResultFile, ErrorBuf, ErrorBufSize);

... 我在执行第二个函数时遇到问题 -

bool reesult2= (DataToStream)(AddressName, Request, RequestSize, ResultStream, ErrorBuf, ErrorBufSize);

它正在编译,但运行时出现访问冲突。

有人可以帮我了解 - 如何正确使用来自 (Delphi) 的 IStream 数据类型?

当我将 ResultStream 声明为 nullptr 指针并使用不正确的连接地址调用 DataToStream 函数时,函数返回“连接错误” - 因此它被正确导入并且主要问题是从函数返回 IStream。

【问题讨论】:

    标签: c++ delphi dll istream loadlibrary


    【解决方案1】:

    您对IStream 的翻译不正确。 DLL 使用COM IStream interface。您不能用 C++ 的 std::istream 类替换它。您需要使用实现IStream 接口的COM 对象。例如,要以IStream 访问文件,您可以使用Win32 的SHCreateStreamOnFileEx() 函数。

    【讨论】:

      【解决方案2】:

      感谢雷米·勒博!

      HRESULT GetFileStream(
      _In_ LPCWSTR fullFileName,
      _Outptr_ IStream** stream)
      
      {
      HRESULT hr = S_OK;
      
      // Create stream for writing the file
      if (SUCCEEDED(hr))
      {
          hr = SHCreateStreamOnFileEx(
              fullFileName,
              STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
              0, // default file attributes
              TRUE, // create file if it does not exist
              NULL, // no template
              stream);
      }
      return hr;
      }
      

      在类型定义中:

      IStream *,  //ResultStream: IStream
      

      ..

      LPCWSTR filename = L"path\\to\\file.txt";
      IStream* ResultStream = NULL;
      HRESULT hr = GetFileStream(filename, &ResultStream);
      

      ..

      bool result = (CallRK7XMLRPCToStream)(AddressName, Request, RequestSize, ResultStream, ErrorBuf, ErrorBufSize);
      

      这里是使用 SHCreateStreamOnFileEx 的一个很好的例子:

      https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/AppxPackingCreateBundle/cpp/CreateBundle.cpp

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-22
        • 1970-01-01
        相关资源
        最近更新 更多