【问题标题】:Win32 DLL Not Returning correct dataWin32 DLL 不返回正确的数据
【发布时间】:2020-07-01 21:39:32
【问题描述】:

我对 C++ 编程非常陌生。我有一个可以利用 Win32 DLL 的第 3 方应用程序。我正在处理的测试项目编译没有错误,但在使用中似乎并没有真正返回预期的数据。

使用下面的函数 Foo,期望传入的 char 数组将返回相同的值。

相反,无论在我的第 3 方应用程序中传递的数据如何,都只会看到返回值:0

我怀疑我没有正确使用指针'char *data_out'。


DemoLib.h:

#pragma once

#define DLL_EXP extern "C" __declspec(dllexport)
DLL_EXP void Foo(char* data_in, char *data_out);

DemoLib.cpp:

#include "stdafx.h"
#include "DemoLib.h"
#include <iostream>

DLL_EXP void Foo(char* data_in, char *data_out)
{
    int a_size = sizeof(data_in) / sizeof(char);
    std::string s_a = convertToString(data_in, a_size);

    char strArray[100];
    strcpy_s(strArray, s_a.c_str());

    data_out = strArray;
}

std::string convertToString(char* a, int size)
{
    int i;
    std::string s = "";
    for (i = 0; i < size; i++) {
        s = s + a[i];
    }
    return s;
}

Exports.def:

LIBRARY DemoLib
EXPORTS
   Foo   @1

【问题讨论】:

  • 检查sizeof(data_in),你不能返回一个指向本地数组的指针(strArray)。函数返回时会销毁。

标签: c++


【解决方案1】:

您的代码中有几个问题。一、行:

int a_size = sizeof(data_in) / sizeof(char);

不会给你data_in 字符串的长度!相反,它将为您提供一个(固定)值,该值是指针大小除以字符大小。所以,假设你有一个 C 风格的、以 null 结尾的字符串,使用这个:

int a_size = int(strlen(data_in));

第二,你的台词:

data_out = strArray;

不会将字符串数据从strArray 复制到data_out!相反,它只是将data_out 保存的指针值(地址)替换为(本地)strArray 数组的地址。 (但是,这不会改变调用模块中任何指针的值。)

这里你需要做的,实际上是将std::string中的数据直接复制data_out参数指向的字符串指向中(假设它是一个足够大的缓冲区)。

考虑到这些变化,您的 Foo 函数可能如下所示:

DLL_EXP void Foo(char* data_in, char *data_out)
{
    int a_size = int(strlen(data_in)); // Note: "strlen" returns a "size_t" (unsigned) type
    std::string s_a = convertToString(data_in, a_size);
    strcpy(data_out, s_a.c_str());
}


或者,如果您确实希望函数返回指向某些本地数据的指针,那么您将: (a) 需要声明该本地数据static; (b) 将相应的参数设为 pointer-to-pointer
DLL_EXP void Foo(char* data_in, char** data_out)
{
    int a_size = int(strlen(data_in)); // Note: "strlen" returns a "size_t" (unsigned) type
    std::string s_a = convertToString(data_in, a_size);
    static char strArray[100];
    strcpy(strArray, s_a.c_str());
    *data_out = strArray;
}

【讨论】:

  • 谢谢。但是,在您的第一个代码块示例中,我收到错误:错误 C2660 'strcpy_s': function does not take 2 arguments
  • @jonno 哎呀!对此感到抱歉 - 我没有检查 strcpy_s 的使用,而不仅仅是简单的旧 strcpy(现已编辑)。如果您真的想使用strcpy_s 调用,只需将(目标的)最大大小作为第二个参数添加:100 在第二个代码块中,或者在第一个中添加任何缓冲区长度。有关strcpy_s 的讨论,请参阅here
  • 成功!谢谢你。我坚持使用 strcpy_s 并添加了最大大小,因为使用 strcpy,生成了编译错误:“此函数或变量可能不安全。请考虑改用 strcpy_s。禁用弃用...”
  • FWIW :使用您的第二个代码块示例,项目已编译,但是,当将 DLL 与我的第 3 方应用程序一起使用时,无论 data_in 值如何,data_out 返回:Ðwl
  • 但是请记住,在第二种情况下,您的调用函数需要传递一个指针的地址!所以:char* answer; ...然后是Foo(in_data, &amp;answer);。如果您无法更改调用应用程序(第 3 方?),那么您将必须坚持第一个选项 - 因为您无法更改已构建应用程序中的函数签名。
猜你喜欢
  • 2019-11-22
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
相关资源
最近更新 更多