【问题标题】:Return value from DLL functionDLL 函数的返回值
【发布时间】:2013-03-12 16:48:42
【问题描述】:

我知道 DLL 通常有自己的堆来存储变量。我的 DLL 函数需要一个指向 wchar_t 变量的指针,每当我尝试将值放入其中时,它都会简单地退出函数,留下指针指向我假设的错误位置是因为堆被破坏了。

如果我的 DLL 函数出现某种需要传回的数据,有人可以给我一个示例,说明如何将字符串格式的数据返回到原始主函数吗?

使用 Visual Studio 2010。

编辑:我可以提供一些示例代码,但我没有看到重点,因为我只是要求一个示例/解释如何处理与 dll 及其函数相关的内存。问我您需要什么信息,我会尽力提供。

好吧,为了让你们了解应用程序的功能,它是一个 COM 服务器 DLL。接口是IProperty,对象叫做PropertyObject。 DLL 是由我使用 PropertyObject 方法单独构建的。这个方法,Getproperty,是我正在研究的方法。

STDMETHODIMP PropertyObject::GetProperty(int arg1, wchar_t* arg2)
{
    arg2 = L"Test";
    cout << *arg2 << endl;
    return S_OK;
}

int main()
{

CoInitialize(NULL);

IClassFactory * pClassFactory = NULL;
HRESULT hr;
hr  = CoGetClassObject(
CLSID_PropertyObject,
CLSCTX_SERVER,
NULL,
IID_IClassFactory,
(void **) &pClassFactory);

if (SUCCEEDED(hr))
{
    wchar_t x = NULL;
    IProperty *pProperty = NULL;

    hr = pClassFactory->CreateInstance(NULL, IID_IProperty, (void **) &pProperty);
    hr = pProperty->GetProperty(2, &x);
    cout << x << endl;
}
    return 0;
}

【问题讨论】:

  • 您现有的代码会有所帮助。然后我们可以更好地看到您正在尝试做的事情。很可能您在尝试写入之前未能分配内存。
  • 是什么让您认为每个 DLL 都有自己的堆?我至少在三种不同的环境中广泛使用了 DLL,而且我从来没有遇到过在一个 DLL 上分配和在另一个 DLL 上释放的问题。 (我在一个 DLL 中构建时遇到问题,在另一个 DLL 中执行 dynamic_cast。)
  • 这不仅仅是一个DLL“函数”;这是一个COM接口方法。如果您打算使用 COM 和较低级别的接口(不像 IDispatch 或符合自动化的双接口,如果这对您来说听起来像是一门外语,也许这应该告诉您一些事情)我会强烈 建议您花时间学习正确使用 IDL(接口定义语言)。例如,您的代码应该使用[size_is] 属性来传递缓冲区空间(实际上,BSTR 输出参数会更合适)。

标签: c++ function dll


【解决方案1】:

如果您 100% 确定所有参与的程序都是使用相同版本的 Visual Studio 编译的(这意味着它们都使用 std::string 所属的相同版本的 STL),您可以使用std::string 类。

如果它需要可互操作,最好的办法是传入一个 char* 和一个长度并写入提供的缓冲区。让调用者处理内存。这是相当 C 风格的,但也是您最安全的选择。

【讨论】:

    【解决方案2】:

    原来我还在考虑像普通字符数组一样的 wchar_t 指针。这是我修改后的代码:

    STDMETHODIMP PropertyObject::GetProperty(int arg1, wchar_t* arg2)
    {
        wcscpy(arg2, L"Test"); // This is the function that i needed to be using. 
        return S_OK;
    }
    
    
    
    int main()
    {
        CoInitialize(NULL);
    
    IClassFactory * pClassFactory = NULL;
    HRESULT hr;
    hr  = CoGetClassObject(
    CLSID_PropertyObject,
    CLSCTX_SERVER,
    NULL,
    IID_IClassFactory,
    (void **) &pClassFactory);
    
    if (SUCCEEDED(hr))
    {
        wchar_t *x = new wchar_t; // Before, this was a normal variable. Changed it to a pointer. 
        IProperty *pProperty = NULL;
    
        hr = pClassFactory->CreateInstance(NULL, IID_IProperty, (void **) &pProperty);
        hr = pProperty->GetProperty(2, x); // Passed the pointer instead of an address to a normal variable. 
        wcout << x << endl; // wcout instead of cout. It worked. 
    }
        return 0;
    }
    

    【讨论】:

    • “原来我还在考虑像普通字符数组一样的 wchar_t 指针。”那不是真正的问题。问题是您正在修改指针、地址,而不是填充缓冲区。
    猜你喜欢
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    相关资源
    最近更新 更多