惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
I
InfoQ
Engineering at Meta
Engineering at Meta
Jina AI
Jina AI
Recent Announcements
Recent Announcements
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
D
Docker
Microsoft Security Blog
Microsoft Security Blog
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
博客园 - Franky
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
B
Blog RSS Feed
WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
月光博客
月光博客
罗磊的独立博客

博客园 - yesry

程序员专用IM新版本发布,诸多创新非模仿 VC的强大 + ExtJS的漂亮 + (MySQL+SQlite)数据库 + JavaScript的动态语言的灵活 学生的福音:做错之题管理 Google 和 baidu 搜索结果二次加工 键鼠模拟的妙用 汉编卷土重来? 用贾樟柯访谈评《疯狂的程序员》 Widgets 引擎的设计和实现 Duceland Widgets Engine 例子一 作为软件从业员面对番茄事件的尴尬立场 招聘Windows API 熟悉人 招IE插件精通人 史上最不安全的浏览器——Dangerous Browser VC调用 JavaScript 难题:如何使当前程序的对象进入脚本 PHP能参与桌面项目吗?适合吗?——C#客户端 嵌入 PHP 一例 互联网公司老板的十大谎言之解——时间成本和竞争成本 我在外资公司的2个月 让大家见识一下新一代分析源代码生成流程图的东东吧 如何进行界面和业务逻辑分开的原型化开发
通过桥接器,Java调用任何DLL
yesry · 2009-03-15 · via 博客园 - yesry

大家知道,Java调用DLL有个特别的地方,就是DLL的输出函数需要特别的名字:
JNIEXPORT void JNICALL Java_类名_函数名
  (JNIEnv *, jclass, 其他参数)

{

}

总是要求DLL函数有 Java_ 开头,调用USER32.DLL中的 GetWindowText 那要怎么做呢?直接调用是不可能的了,下面介绍通过桥接器,实现Java调用任何API,或者类似API的任何DLL的方法。

先看运行效果:

这是把 JFrame 通过 API 中的 SetWindowRgn 函数改变成圆角窗口。

这个桥接器的准备工作可以参考VC写的源代码。这里主要介绍的是Java部分的代码:

1 API 部分

public class MyAPI{
    
public static dobject4j os_api=new dobject4j("OSAPI");
    public static dValue GetWindowText(dValue hWnd){
        dobject4j param
=new dobject4j("ApiParams");
        
        param.invoke(
"AppendHandlePointer",hWnd);
        param.invoke(
"AllocAsciiStringBuffer",new dValue(260));
        param.invoke(
"AppendUnsignedLong",new dValue(260));
        
        os_api.invoke(
"CallOSAPI",new dValue("USER32.DLL"),new dValue("GetWindowTextA"),new dValue(param));
        
return param.invoke("ReadAsciiString",new dValue(4));
    }
    
   
public static dValue SetWindowRgn(dValue hWnd,dValue hRgn,dValue bRedraw){
        dobject4j param=
new dobject4j("ApiParams");
        
        param.invoke("AppendHandlePointer",hWnd);
        param.invoke("AppendHandlePointer",hRgn);
        param.invoke("AppendUnsignedLong",bRedraw);
        
        dValue ret=os_api.invoke("CallOSAPI",
new dValue("USER32.DLL"),new dValue("SetWindowRgn"),new  dValue(param));
        param=null;
       
return ret;
    }
   
//其他API的代码可以下载后看看。下载的.dwidget文件是zip格式的,改名.zip解压后即可。
}

2 应用实现部分

    public void StartupMe(){
        frame
=new JFrame("Swing Application");
        ................
        createComponents(frame);
        frame.setLocation(
300,220);
        frame.setSize(
300,130);
        String title
="round JFrame";
        frame.setTitle(title);
        frame.setVisible(
true);
        
        ................        dValue desktop=MyAPI.GetDesktopWindow();
        dValue h
=MyAPI.FindWindowEx(desktop,null,new dValue("javax.swing.JFrame"),new dValue(title));
        dValue hParentRgn=MyAPI.CreateRoundRectRgn(new dValue(13),new dValue(3),
                                 new dValue(290),new dValue(120),new dValue(15),new dValue(15));
        MyAPI.SetWindowRgn(h,hParentRgn,
new dValue(true));
        MyAPI.DeleteObject(hParentRgn);
    }

桥接器的2个重要的类分别是 OSAPIApiParamsOSAPI 负责API的调用实现,ApiParams 负责参数组织。OSAPI 的 CallOSAPI 方法 第一个参数是DLL文件名,像上述的USER32.DLL,第二个参数是方法的名字,要注意的是,Windows API 很多是区分 ANSI 和 Unicode ,就像我们熟悉的GetWindowText() 就分别有GetWindowTextA() GetWindowTextW() 两个对应于 ANSI 和 Unicode ,第三个参数是API的参数。ApiParams 的方法有很多,都是支持各种类型参数用的,例如 AppendUnsignedLong() 方法支持 DWORD 类型,AppendHandlePointer() 支持各种句柄。ApiParams还可以嵌套,用 AppendStructurePointer() 方法支持嵌套结构体指针,用 AppendStructure()  方法支持嵌套结构体,等等。

点击这里仅下载本例代码,下载后的.dwidget改名.zip文件解压即可

点击这里下载整个运行程序

点击这里下载这个IE内核浏览器源代码(不含msscript.ocx调用机制部分源代码,这部分是DLL形式提供的)