使用目标文件调用winapi函数[关闭]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用目标文件调用winapi函数[关闭]相关的知识,希望对你有一定的参考价值。

我正在使用.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("
System 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;
}

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

链接选项:

cl / c / nologo / c / MT / I. testprogram.c testprogram.c

LINK / 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测试程序中,输出为total = 512003928064。

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

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

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

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

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

答案

你说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 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
");
    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();
}

以上是关于使用目标文件调用winapi函数[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何防止我的函数在RemoveDirectory()WINAPI中延迟删除?

由于参数错误,WINAPI GetRawInputData 出错 [关闭]

C#调用WinApi?

WinAPI ReadFile 返回损坏的数据[关闭]

VC ++ WINAPI窗体:找不到标识符(C3861错误)

如何使用C#操作WinAPI