且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JNI不与__stdcall工作

更新时间:2023-11-29 20:56:52

有关32位的DLL文件正在使用JNI时,code有没有通常被编译 __ STDCALL 装饰品 - 即code不能有 @N 后缀的符号名;但它仍然需要在 __ STDCALL要编译模式。

For 32 bit DLLs being used by jni, the code has to be compiled without the usual __stdcall adornments - i.e. the code can't have the @N postfix on the symbol name; but it still needs to be compiled in __stdcall mode.

在编译的MinGW下的DLL,您需要添加的选项 - 杀 - 以来的链接。这是使用 -Wl一般过去了, - 杀 - 以。这将导致要删除的 @N 后缀,因此会显示为一个简单的符号,可在由JVM运行时被链接。该选项可以缩写为轮候册,-k 以及

When compiling the dll under mingw, you need to add the option --kill-at to the linker. This is generally passed using -Wl,--kill-at. This will cause the @N postfix to be removed, and so appear as a simple symbol which can be linked at run-time by the JVM. The option can be abbreviated to -Wl,-k as well.

另一种方法是使用一个映射文件,其中出口符号在其重整的形式,这是与微软自己的Visual Studio编译器在编译时所使用的最常见的机制。

An alternative is to use a map file, which exports the symbols in their unmangled form, which is the mechanism that's used most often when compiling with microsoft's own visual studio compiler.

这是pretty不良记录,你会得到所产生的误差,当它发生不利于太清楚了。

This is pretty poorly documented, and the resulting error you get when it happens doesn't help too well.

我建议在看 JNA ,这使得编写本地code包装简单了很多,在这种情况下,就意味着没有C ++ code需要。

I'd recommend looking at JNA, which makes writing native code wrappers a lot simpler, and in this case would mean no C++ code needed.

在JNA code来完成这个样子:

The JNA code to accomplish this looks like:

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.WPARAM;

public class JNAMonitorTrigger {
    public void monitor(LPARAM param) {
        User32.INSTANCE.PostMessage(WinUser.HWND_BROADCAST,
            WinUser.WM_SYSCOMMAND,
            new WPARAM(0xf170), param);
    }
    public void on() {
        monitor(new LPARAM(-1));
    }

    public void off() {
        monitor(new LPARAM(2));
    }

    public static void main(String args[]) throws Exception {
        JNAMonitorTrigger me = new JNAMonitorTrigger();
        me.off();
        Thread.sleep(1000);
        me.on();
    }
};