标签: cdecl

为什么在违反调用约定的情况下PInvoke不会崩溃(在.NET 3.5中)?

我的解决方案有一个非托管C++ DLL,它导出一个函数,一个托管应用程序PInvokes这个函数.

我刚刚将解决方案从.NET 3.5转换为.NET 4.0并得到了这个PInvokeStackImbalance "对PInvoke函数的调用[...]已经使堆栈失衡"异常.事实证明,我正在调用__cdecl'ed函数,因为它是__stdcall:

C++部分(被调用者):

__declspec(dllexport) double TestFunction(int param1, int param2); // by default is __cdecl
Run Code Online (Sandbox Code Playgroud)

C#部分(来电者):

[DllImport("TestLib.dll")] // by default is CallingConvention.StdCall
private static extern double TestFunction(int param1, int param2);
Run Code Online (Sandbox Code Playgroud)

所以,我已经修复了这个bug,但现在我对.NET 3.5中的工作原理感兴趣吗?当没有人(既不是被叫者也不是调用者)清理堆栈时,为什么(多次重复)情况没有引起堆栈溢出或其他一些不当行为,但只是工作正常?Pnvoke中是否有某种检查,就像Raymond Chen在他的文章中提到的那样?这也很有趣,为什么相反类型的破坏约定(让__stdcall被调用者像被__cdecl一样被PInvoked)根本不起作用,导致只有EntryPointNotFoundException.

.net pinvoke cdecl calling-convention stdcall

4
推荐指数
2
解决办法
1435
查看次数

是否可以在__stdcall中输出导出的函数并且名称为unmangled?

我正在开发一个项目来生成用于离线测试的虚拟DLL.我们有真正的DLL及其头文件,虽然它们似乎不兼容.DLL中的名称是未解码的,但函数转发声明声明被称为__stdcall:

example.h文件

DWORD __stdcall DoSomething(byte aByte);
Run Code Online (Sandbox Code Playgroud)

Dependency Walker中的example.dll:

2 (0x0002)   2 (0x0002)   DoSomething   0x000831C0
Run Code Online (Sandbox Code Playgroud)

据我所知,如果可以在__stdcall约定中导出函数,其名称应该在依赖walker中读取:

2 (0x0002)   2 (0x0002)   _DoSomething@1   0x000831C0
Run Code Online (Sandbox Code Playgroud)

这是否意味着我们的头文件与编译的DLL不对应或者我错过了什么?

最终,我如何形成虚拟函数的导出,其行为方式与我正在模拟的真实DLL相同?

c++ dll cdecl stdcall dllexport

3
推荐指数
1
解决办法
498
查看次数

将参数从C传递给汇编?

如何将参数从C main函数传递给汇编函数?我知道我的自定义函数必须看起来像:

void function(char *somedata) __attribute__((cdecl));
Run Code Online (Sandbox Code Playgroud)

现在我将如何somedata在程序集文件中使用.我的操作系统是Linux Ubuntu,我的处理器是x86.

c assembly cdecl

2
推荐指数
1
解决办法
7082
查看次数

Dumpbin显示奇怪的方法名称(在MS Visual C++中生成导出功能)

我在VS中创建了新的Win32项目,并为此目的选择了动态库(*.dll).

我在主文件中定义了一些导出函数:

__declspec(dllexport)
int TestCall(void)
{
    int value = 4 / 2;
    std::cout << typeid(value).name() << std::endl;
    return value;
}

__declspec(dllexport)
void SwapMe(int *first, int *second)
{
    int tmp = *first;
    *first = *second;
    *second = tmp;
}
Run Code Online (Sandbox Code Playgroud)

当我看到dumpin/exports时,我得到了:

ordinal hint RVA      name

      1    0 00001010 ?SwapMe@@YAXPEAH0@Z
      2    1 00001270 ?TestCall@@YAHXZ
Run Code Online (Sandbox Code Playgroud)

我正在调用C#这样的版本:

[DllImport(@"lib1.dll", EntryPoint = "?TestCall@@YAHXZ",
CallingConvention = CallingConvention.Cdecl)]
static extern int TestCall();
Run Code Online (Sandbox Code Playgroud)

这不是使用导出方法的正确形式.我在C++ DLL项目中为导出方法生成这样的名称失败了吗?

dll pinvoke cdecl dllexport dumpbin

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

为什么没有同伴指示离开?

为什么在 x86 上没有伴随指令离开?那样,

pushl   %ebp
movl    %esp,%ebp
pushl   $3
popl    %eax
leave
ret
Run Code Online (Sandbox Code Playgroud)

可以变成:

enter #or something
pushl   $3
popl    %eax
leave
ret
Run Code Online (Sandbox Code Playgroud)

一般来说,这不是更快吗?

x86 assembly cdecl

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

__cdecl 和 (void) 是什么意思?

我目前正在使用 WSA 对 tcp/ip 服务器进行编程。经过一些故障排除后,我的一个朋友说我应该使用bool __cdecl winsock_server ( void )而不是bool winsock_server().

但他没有向我解释什么__cdecl(void) 正在做什么。我已经知道这__cdecl改变了在汇编程序级别上将参数放入堆栈的方式,但这是什么(void)意思?

我应该指出我是 C++ 的新手。我之前只用 C# 和 VB.NET 编程。

提前致谢!

c++ cdecl void

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

标签 统计

cdecl ×6

assembly ×2

c++ ×2

dll ×2

dllexport ×2

pinvoke ×2

stdcall ×2

.net ×1

c ×1

calling-convention ×1

dumpbin ×1

void ×1

x86 ×1