java利用jni調用dll方法


准備工作:

需要用到的插件jni4net:這個需要去官網下載:https://sourceforge.net/projects/jni4net/files/

(1)     jni4net 是一個開源的項目

(2)     jni4net-0.8.8.0.zip 中是工具的所有文件,包含示例

下載后解壓是這樣的

 打開lib下邊有你需要用到的jar包和dll這是關鍵。

創建C#程序:

打開vs創建一個類庫com.demo.lib項目,寫上測試程序。

HelloWorld.cs

result.cs

User.cs

 編譯成功之后,會在bin下的Debug下生成相關的dll。

使用proxygen工具來生成proxy類.

jni4net-0.8.8.0-bin\bin下就有proxygen工具,可以直接在該目錄下打開cmd,執行命令:.\proxygen.exe "DLL所在路徑" -wd "java項目根路徑"

此處我是直接在bin下建了一個文件夾,用於存放生成的文件。生成之后,需要將所有文件拷到java項目根路徑下。

執行后會出現以下文件

然后將jni4net的相關文件都拷到java項目的根路徑下,執行build.cmd

里面的腳本需要修改成你對應的項目路徑。

錯誤提示:

執行過程中如果提示你某些程序包不存在,說明你沒有放到項目路徑下,或者說,你沒有項目中沒有相關的jar包。

如果提示你csc.exe是不可執行的命令,說明你沒有配置環境變量,將PATH中加上路徑:C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319(環境變量之間用英文分號;隔開),其他方法也可以實現。

執行成功之后會生成一個dll一個jar。

 這兩個是后邊需要用到的。

java部分

我采用的開發工具是IDEA,我在項目根目錄下,建了一個文件夾叫,lib,然后將兩個jar包拷到lib下面。記住此處要將jar包添加到項目中去。

 

 dll的話,我是采用的第三方路徑,別的方法也可以,我簡單闡述一下我的方法。我將剩余的dll拷到e盤下dll文件夾中,

然后在配置文件中,配置上相關的路徑。

 在application.yml加個配置信息

        plugins:
            dll:
              path:
e:/dll #dll所在路徑
               files: com.demo.lib.j4n.dll #加載的dll文件名,是生成的那個

由於我們是采用的外部文件夾的形式,因此需要一個類來初始化加載這個配置信息。

 

測試程序:

新建一個demo.java的類,需要將之前讀取到的dll中的信息讀取過去,因此需要這么一個方法:

public List<String> loadPlugins()
{
Logger log = LoggerFactory.getLogger(PluginsLoader.class);
List<String> arr = new ArrayList<>();
String files=pluginsLoader.getFiles().trim();
String path=pluginsLoader.getPath();
if(files.length()>0)
{
File dir = new File(path);
if(dir.exists())
{
log.info("-------start loading plugins,directory is "+path+"-------");
try {
Bridge.init(dir);
String[] fileArr = files.split(",");
for (String f : fileArr) {
File file = new File(dir, f);
if (file.exists()) {
Bridge.LoadAndRegisterAssemblyFrom(file);
arr.add(f);
log.info("plugin loaded:"+f);
} else {
log.warn(f + " not exists,not loaded!");
}
}
log.info("------- load plugins complete -------");
}catch (IOException e)
{
log.error("init bridge failed:"+e.getLocalizedMessage());
}
}
}
return arr;
}
有了這個方法,你就可以調用了
直接上測試程序:
@RequestMapping("/dll")
public String invokeDllFunction()
{
List<String> arr = loadPlugins();
Result rs = null;
User u = new User();
u.setName("張三");
u.SetFirstName("first name");
rs = HelloWorld.StaticGreet(u,"message info");
HelloWorld hw = new HelloWorld();
Result rs2 = hw.Greet(u,"greet info");
return rs.getMessage()+","+rs2.getMessage();
}

示例中,Result、User、HelloWorld三個類都是dll中的,HelloWorld中有一個靜態方法,兩個重載方法,方法參數有類、字符串,返回類型有void有對象。在c#代碼中,User類有一個屬性private String Name{get;set},生成的jar中User的setName於getName是自動給加上的getter、setter;

好了,啟動試試吧:調用結果:

到這里,基本上就完成了。

使用總結

1、執行腳本,生成jar和dll

2、配置dll的路徑等信息

3、將jar添加到java項目並使用

 

備注:

Springboot引入本地jar,並在生成時復制到對應lib下,對應pom.xml配置:

<dependency>
   <groupId>net.sf</groupId>
   <artifactId>jni4net</artifactId>
   <version>0.8.8.0</version>
   <scope>system</scope>
   <systemPath>${project.basedir}/libs/jni4net.j-0.8.8.0.jar
   </systemPath>
</dependency>
<dependency>
   <groupId>com.demo</groupId>
   <artifactId>lib.j4n</artifactId>
   <version>1.0.0</version>
   <scope>system</scope>
   <systemPath>${project.basedir}/libs/com.demo.lib.j4n.jar
   </systemPath>
</dependency>

 

<resources>
   <resource>
      <directory>${project.basedir}/libs</directory>
      <targetPath>BOOT-INF/lib/</targetPath>
      <filtering>false</filtering>
      <includes>
         <include>*.jar</include>
      </includes>
   </resource>
</resources>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM