【问题标题】:Using object file to call winapi functions [closed]使用目标文件调用winapi函数[关闭]
【发布时间】:2017-12-21 07:34:05
【问题描述】:

我正在使用来自.cpp 文件的目标文件,我链接到.c 测试程序。

目标文件中有使用 Win32 API 的函数,例如:

std::string gettheVolumeSize()
{
    //vector for the volume size
    std::stringstream vs;
    std::string myvolumesize;
    std::vector<std::string> volumeSize;
    if (!GetSystemDirectory(infoBuf, INFO_BUFFER_SIZE))
    {

    }
    else {
    //  _tprintf(TEXT("\nSystem Directory:   %s"), infoBuf);
    }
    char* variable;

    variable = getenv("SystemDrive");
    std::string use = std::string(variable);    

    __int64 total, free;
    USES_CONVERSION_EX;
    std::string path;

    //create path for the diskspace request
    path = use + "\\\\";

    printf("%s", path);
    LPWSTR mypath = A2W_EX(path.c_str(), text.length());
    LPCTSTR tt = reinterpret_cast<LPCTSTR>(mypath);
    printf("%ls", tt);
    //fill vector with volumeSize
    GetDiskFreeSpaceEx(tt, NULL, (PULARGE_INTEGER)&total, (PULARGE_INTEGER)&free);  
    printf("%llu", total);
    std::stringstream testit;
    const char* totalSize;
    int roundsize;
    roundsize = round((((__int64)total) / (1024 * 1024 * 1024)));

    vs << round((((__int64)total) / (1024 * 1024 * 1024)));
    vs >> myvolumesize;

    return myvolumesize;
}

我的问题是,当我在.c 测试程序中调用函数时,我现在有不同的volumeSizes

链接选项:

cl /c /nologo /c /MT /I。测试程序.c 测试程序.c

链接 /nologo /OPT:NOREF /NXCOMPAT /DynamicBase /out:test.exe testprogramm.obj SHA1.obj it4ecidtest.obj LIBCPMT.LIB libcmt.lib libvcruntime.lib oldnames.lib kernel32.lib user32.lib netapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib shell32.lib Rpcrt4.lib oleaut32.lib Ole32.lib Wbemuuid.lib wintrust.lib crypt32.lib Ws2_32.lib iphlpapi.lib Psapi.lib advapi32.lib Shlwapi.lib dhcpcsvc.lib userenv.lib atls.lib msvcrtd.lib vcruntimed.lib netapi32.lib Advapi32.lib IPHLPAPI.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

已编辑:

当我调用目标文件中的函数时,输出为1996888586,而在普通.cpp测试程序中,总= 512003928064。

我只是使用printf 来检查值,我不会将输出返回到我的.c 文件:

#include<stdio.h>
#include "it4ecid.h"

int main() {
    printf("Hello World\n");
    char* cstring = getCompositeID();   
    printf("%s", cstring);
    return 0;
}

为了清楚起见:我从我的 .cpp 文件创建一个目标文件,并在用 C 编写的测试程序中调用它的 getCompositeID() 函数。

getCompositeID.cpp 文件中的一个函数,现在只是调用gettheVolumeSize() 函数。

【问题讨论】:

标签: c++ file object compilation


【解决方案1】:

你说getCompositeID()只是调用gettheVolumeSize(),但是前者返回一个char*,而后者返回一个std::string。如果你正在做这样的事情:

char* getCompositeID() {
    return gettheVolumeSize().c_str();
}

然后您的main() 代码将无效指针传递给printf(),这是未定义的行为。

为确保字符串内存在函数调用之后仍然存在,您必须将 std::string 保存到局部静态或全局变量,例如:

char* getCompositeID() {
    static std::string size;
    size = gettheVolumeSize();
    return size.c_str();
}

或者:

static std::string volumeSize;

char* getCompositeID() {
    volumeSize = gettheVolumeSize();
    return volumeSize.c_str();
}

但这两种方法都不是线程安全的。如果你需要线程安全,你可以使用 Thread-Local Storage,例如:

__thread std::string volumeSize;

char* getCompositeID() {
    volumeSize = gettheVolumeSize();
return volumeSize.c_str();
}

否则,让getCompositeID() 动态分配char[]std::string 数据副本并让main() 释放它:

char* getCompositeID() {
    std::string size = gettheVolumeSize();
    char *ret = (char*) malloc(size.length()+1);
    if (ret) strcpy(ret, size.c_str());
    return ret;
}

int main() {
    printf("Hello World\n");
    char* cstring = getCompositeID();
    printf("%s", cstring);
    free(cstring);
    return 0;
}

无论如何,您的gettheVolumeSize() 比它需要的复杂得多,并且其中有错误。它可以大大简化成这样:

std::string gettheVolumeSize() {
    std::string path;

    //create path for the diskspace request
    /*
    char    sysDir[MAX_PATH] = {};
    if (!GetSystemDirectoryA(sysDir, MAX_PATH)) return "";
    printf("%s", sysDir);
    path = sysDir;  
    */
    char *variable = getenv("SystemDrive");
    if (!variable) return "";
    path = std::string(variable) + "\\";
    printf("%s", path.c_str());

    //get volume size
    ULARGE_INTEGER totalSize;
    if (!GetDiskFreeSpaceExA(path.c_str(), NULL, &totalSize, NULL)) return "";
    printf("%llu", totalSize.QuadPart);

    std::ostringstream oss;
    oss << round(double(totalSize.QuadPart) / (1024 * 1024 * 1024));
    return oss.str();
}

【讨论】:

  • if (!GetDiskFreeSpaceExA(path.c_str(), NULL, &total, &free)) return "" 表示 long long 和 Pularge_Integer 类型不兼容
  • @objectfiles 您是否将您的totalfree 变量从__int64 更改为ULARGE_INTEGER?如果是这样,并且您仍然收到错误,那么您在某处对 ULARGE_INTEGER 的定义存在冲突。此代码需要one from the Win32 API
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多