标签: stdcall

VC++阻止所有符号名称装饰

我正在研究一个DLL,它将使用_stdcall调用对话从另一种语言(因此没有导入库和包括dll的头文件)中使用.问题是VC++似乎总是对其导出的符号进行一些名称修饰.我见过的所有引用都说使用extern"C",但这似乎仍然留下了一个前导下划线,并且在导出的名称之后加了一个@加号.

最糟糕的一点是在目标语言中加载扩展dll的自动方式基本上是"func_name = GetProcAddress(dll,"func_name")"所以使用未修饰的名称GetProcAddress失败,并使用装饰名称它抱怨非法变量名称( @ 不被允许) :(

如何让VC++导出一些没有名字装饰的东西呢?

extern "C" __declspec(dllexport) int __stdcall test(int x, const char *str);
Run Code Online (Sandbox Code Playgroud)

DUMPBIN.EXE

00011366 _test @ 8 = @ ILT + 865(_test @ 8)

c++ dll name-mangling stdcall name-decoration

8
推荐指数
1
解决办法
1678
查看次数

在C++中,可变参数函数(在参数列表末尾带有...的函数)必须遵循__cdecl调用约定吗?

我知道__stdcall函数不能有省略号,但我想确保没有支持stdarg.h函数的平台来调用除__cdecl或__stdcall之外的约定.

c++ cdecl variadic-functions stdcall

7
推荐指数
1
解决办法
2141
查看次数

为什么微软定义WINAPI、CALLBACK、APIENTRY都指向__stdcall?

对于曾为负责定义这些宏的 Microsoft 团队工作过、认识为其工作过的人或以其他方式与 Microsoft 团队有任何联系的任何人来说,这是一个好奇的问题。

我明白__stdcall是什么,我知道为什么使用它,我只是不明白为什么微软会为同一件事制作三个单独的宏。我能看到的唯一好处是在源文件中提供一些语义含义,但除此之外,据我所知,它没有提供其他好处。显然这样做是有道理的,我只是想知道它是什么!:)

c macros winapi stdcall

7
推荐指数
1
解决办法
3205
查看次数

结构如何作为参数传递给汇编

结构如何作为参数传递?

由于结构的大小比正常大,各个字段是否顺序通过?

如果是这样,它们是否与正常参数相反?

他们在cdecl和stdcall之间有什么区别吗?

x86 assembly cdecl stdcall

7
推荐指数
1
解决办法
3158
查看次数

从使用stdcall的DLL创建MSVC导入库

我有一个出口的DLL

extern "C" __declspec(dllexport) int __stdcall Foo( void );
Run Code Online (Sandbox Code Playgroud)

dll的转储显示

******************************************************************************
Section:             Exports
File Offset:         00001400 (5120)
  Flags:             00000000
  Time Stamp:        00000000
  Major Version:     0000
  Minor Version:     0000

Exports from simple.dll
  3 exported name(s), 3 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    -------- ---- ---- ----
    00002104    3 0000 std::nothrow
    00001258    2 0001 Foo
    000020F8    1 0002 ___CPPdebugHook

******************************************************************************
Run Code Online (Sandbox Code Playgroud)

我从以下def文件开始:

LIBRARY simple.dll 
EXPORTS
  Foo
Run Code Online (Sandbox Code Playgroud)

这创建了一个包含以下导出的lib文件:

Exports
       ordinal    name
                  _Foo
Run Code Online (Sandbox Code Playgroud)

当我链接到这个库时,msvc链接器抱怨它找不到_Foo @ 0.为了解决这个问题,我在def文件中添加了一个别名.

LIBRARY simple.dll …
Run Code Online (Sandbox Code Playgroud)

import dll stdcall visual-c++

6
推荐指数
1
解决办法
3588
查看次数

64位C++传递具有"不同"调用约定作为参数的函数会产生不明确的错误

我的目标是使用__cdecl和__stdcall调用约定轻松提取任意函数的原型.它在32位工作正常.唯一改变的是模板函数参数中的调用约定.

根据维基百科的说法: "在Windows环境中编译x64架构时(无论是使用Microsoft还是非Microsoft工具),只有一个调用约定 - 这里描述的那个,所以stdcall,thiscall,cdecl,fastcall等. ,现在都是一样的."

这打破了64位的代码.即使调用约定相同,将函数作为参数传递仍然需要使用正确的命名法.IE如果函数定义为__stdcall,则必须将其传递给接受__stdcall的包装器.即使__cdecl相同,您仍然必须将定义为__cdecl的函数传递给接受__cdecl的包装器.

以32位工作的示例:

template<typename T, typename... Args>
struct WrapperSTD { typedef T(__stdcall *Functor)(Args...); };

template<typename T, typename... Args>
struct WrapperC { typedef T(*Functor)(Args...); };

template<typename T, typename... Args>
WrapperSTD<T, Args...> wrap(T(__stdcall *func)(Args...)) {
    return WrapperSTD<T, Args...>{};
}
template<typename T, typename... Args>
WrapperC<T, Args...> wrap(T(*func)(Args...)) {
    return WrapperC<T, Args...>{};
}
Run Code Online (Sandbox Code Playgroud)

我的目标是能够运行,例如:

using MsgBoxProto = decltype(wrap(MessageBoxA))::Functor;
Run Code Online (Sandbox Code Playgroud)

这适用于32位.但是,由于__stdcall和__cdecl在x64中显然是相同的,因此它不能在64位中工作并引发错误,表示调用是不明确的.它还告诉我模板已经定义.直观地说,似乎我能够将带有__cdecl的函数传递给这个__stdcall函数,因为编译器认为它们是相同的.但是,这不起作用:

template<typename T, typename... Args>
struct WrapperFC { typedef T(__stdcall *Functor)(Args...); };

template<typename T, typename... Args>
WrapperFC<T, Args...> wrap(T(__stdcall …
Run Code Online (Sandbox Code Playgroud)

c++ 64-bit cdecl calling-convention stdcall

6
推荐指数
1
解决办法
870
查看次数

为什么Microsoft选择stdcall作为他们的API约定?

有充分的理由吗?

他们的内部函数(未导出)是否也是stdcall约定?

windows winapi calling-convention stdcall

5
推荐指数
1
解决办法
1053
查看次数

调用可以是cdecl或stdcall的函数

我需要编写调用外部函数的代码,该函数可以是32位Windows应用程序中的stdcall调用或cdecl。
我的代码(调用者)无法事先知道将要使用的代码。现在,如果我尝试从定义为stdcall的调用站点中调用cdecl函数,则会出现一个checkEsp异常对话框,并且我猜那是有充分原因的。
有什么办法吗?

windows assembly 32-bit cdecl stdcall

5
推荐指数
1
解决办法
398
查看次数

调用Windows API函数(stdcall)的符号扩展规则是什么?这需要从Go调用WInAPI,这对int类型是严格的

哎呀,当我做出这个答案时,有一件事我忘记了,而且我对自己并不是很确定,而且我似乎无法在MSDN和谷歌以及Stack Overflow搜索中找到相关信息.

Windows API中有许多地方使用负数,或者数字太大而无法使用有符号整数; 例如CW_USEDEFAULT,INVALID_HANDLE_VALUE,GWLP_USERDATA,等等.在C的世界里,一切都很好,花花公子:语言的整数提升规则得到了拯救.

但在Go中,我必须将所有参数传递给函数uintptr(相当于C的uintptr_t).函数的返回值也以这种方式返回,然后我需要进行比较.Go不允许整数提升,并且它不允许您在编译时将有符号常量表达式转换为无符号表达式.

现在,我在我的UI库中设置了一些用于处理这些常量的jerry-rig.(这是这个解决方案在行动中的样子.)但是,我对这个解决方案并不满意; 我觉得它喜欢ABI的事情,我想要完全确定我在做什么.

所以我的问题是:将签名值传递给Windows API函数时如何处理?返回时如何处理?

我的所有常量都是自动生成的(示例输出).自动生成器使用C ffi,我宁愿不用于主项目,因为我可以直接调用DLL(这也使得交叉编译至少在今年剩余时间内更容易).如果我可以以某种方式利用它,例如通过将所有内容都变成表单的C端变量

uintptr_t x_CONST_NAME = (uintptr_t) (CONST_NAME);
Run Code Online (Sandbox Code Playgroud)

这会有所帮助.但如果没有这个答案我就不能这样做.

谢谢!

更新

IRC上的某个人将其改为不同(重新格式化以避免水平滚动):

[19:13] <FraGag> basically, you're asking whether an int with a value of -1
                 will be returned as 0x00000000FFFFFFFF or as 0xFFFFFFFFFFFFFFFF
                 if an int is 4 bytes and an uintptr is 8 bytes
Run Code Online (Sandbox Code Playgroud)

基本上这个,但专门用于Windows API互操作,传入的参数,无论uintptr大小.

c winapi interop go stdcall

5
推荐指数
1
解决办法
210
查看次数

如何从未修饰的stdcall DLL自动生成导入库?

处理从DLL创建LIB的一般方法在如何在有.dll文件和头文件的情况下创建.lib文件中描述- 仍然是为具有未修饰stdcall函数的DLL创建导入库(例如核心WinAPI DLL kernel32.dll等) .),一个要经过一个相当漫长和复杂的过程(如例如描述这里).对于具有许多功能的DLL,此过程非常耗时且容易出错 - 当原始DLL发生更改时(例如,由于供应商更新),它在自动渲染情况下也很容易失败.

有没有一种有效的自动化方法?

c++ dll name-mangling stdcall

5
推荐指数
1
解决办法
872
查看次数