Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need support Windows-style DLL export function names #14559

Closed
liigo opened this issue May 31, 2014 · 11 comments
Closed

Need support Windows-style DLL export function names #14559

liigo opened this issue May 31, 2014 · 11 comments
Labels
O-windows Operating system: Windows

Comments

@liigo
Copy link
Contributor

liigo commented May 31, 2014

#[no_mangle]
pub extern "stdcall" fn add(x: i32, y: i32) -> i32 {
    x + y
}

After compiled to DLL, the exported function name is add@8.
But we need a way to export it as add (instead of add@x).
Most Windows API are named without "@x".

@klutzy
Copy link
Contributor

klutzy commented May 31, 2014

it's stdcall symbol decoration. Win32 stdcall requires symbol exported as _<name>@<size of parameters>. (So most windows apis are actually exported with @x)

@liigo
Copy link
Contributor Author

liigo commented May 31, 2014

@klutzy Can you tell me which windows api is exported with @x in its name?

kernel32

@klutzy
Copy link
Contributor

klutzy commented May 31, 2014

It's just that dependency walker understands stdcall convention.

$ nm /c/Program\ Files/Microsoft\ SDKs/Windows/v7.1/Lib/User32.lib 2>&1 | grep MessageBoxW
00000000 I __imp__MessageBoxW@16
00000000 T _MessageBoxW@16

Indeed gcc also adds @x:

$ cat c.c
#include <windows.h>
__stdcall int add(int a, int b) { return a + b; }
void call_stdcall(void) { MessageBoxW(0, 0, 0, 0); }

$ gcc -c c.c -o c.o
$ nm c.o
00000000 b .bss
00000000 d .data
00000000 r .eh_frame
00000000 r .rdata$zzz
00000000 t .text
         U __imp__MessageBoxW@16
00000000 T _add@8
0000000f T _call_stdcall

@alexcrichton
Copy link
Member

Closing, it sounds like this is normal behavior.

@liigo
Copy link
Contributor Author

liigo commented Jun 3, 2014

@alexcrichton @klutzy You misunderstand.
I'm not saying export "FnName@xx" names is a wrong behavior. I just saying we need a new feature to export "FnName"(without @XX) names to follow Windows-DLL-style on Windows platform. Most Windows DLL functions (including Windows API) can be load dynamically by GetProcAddress, for example:
GetProcAddress(hModule, "MessageBoxW") // not "MessageBoxW@16"
Most 3rd plugin systems (Lua extensions etc.) on Windows depend on this.

@alexcrichton
Copy link
Member

Do you have some example code which does not work as expected? If C++ is doing the same thing it seems like there's no bug here.

@klutzy
Copy link
Contributor

klutzy commented Jun 3, 2014

Ok, I now understand what you mean: you want symbol dllexported as other name.

However this is usually done by linker and no language support is required, even on C/C++.
You must prepare .def file with EXPORTS section and give it to linker. For example:

$ cat c.c
__stdcall void std_func(void) {}

$ cat c.def
LIBRARY c
EXPORTS
  std_func=std_func@0

$ gcc c.c c.def -shared -o c.dll  # (c.def will be passed to ld)

\> dumpbin /exports c.dll
...
    ordinal hint RVA      name

          1    0 00001280 std_func

then c.dll has _std_func rather than _std_func@0.
(I don't know much about VC toolchain, but I've heard that it also need .def file.)
So what you really need is to write .def file and pass it to linker.

However, we don't explicitly export symbols so adding .def files will cause other pub symbols not exported. This should be fixed - see #7196.

(Or, the easiest solution is using extern "C" rather than extern "stdcall".)

@liigo
Copy link
Contributor Author

liigo commented Jun 3, 2014

Let's leave C/C++ aside, we talk about Rust: How to do it? (and can we make it easier?)

@klutzy
Copy link
Contributor

klutzy commented Jun 3, 2014

Basically same: you can write .def file and give it to linker.

$ cat a.rs
#![crate_type = "dylib"]
#[no_mangle]
pub extern "stdcall" fn std_func() {}

$ cat a.def
LIBRARY a
EXPORTS
  std_func=std_func@0

$ rustc a.rs -C link-args="a.def"

(but this currently causes other symbols not exported as described at #7196)

@liigo
Copy link
Contributor Author

liigo commented Jun 3, 2014

@alexcrichton

Rust: (compile to a DLL)

#[no_mangle]
pub extern "stdcall" fn add(x: i32, y: i32) -> i32 {
    x + y
}

C/C++ (or others):

typedef int (__stdcall *PFN_ADD) (int x, int y);
PFN_ADD pAdd = (PFN_ADD) GetProcAddress(hDllModule, "add"); // load fn by name
pAdd(1, 2);

I expect that Rust DLL export a function named "add" (not "add@x"), and can be load by this name in other languages. Most 3rd plugin systems expected this, such as Lua extensions.

NOTE: I'm not filing a bug (I don't think there is a bug), I'm asking for new feature.

@liigo
Copy link
Contributor Author

liigo commented Jun 3, 2014

@klutzy Thank you! I tried it, and it works.

bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
internal: Skip code lens resolution for mismatched document versions

Closes rust-lang/rust-analyzer#12718
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

4 participants