利用jna调用使用C#的dll文件

目前所做java项目中有部分模块需要使用客户提供的dll动态库文件中封装的算法,客户提供了一个dll文件以及C#语言编写的可执行文件实例,算法具体代码未提供。之前只涉及过利用jna调用c++所生成的dll文件,最终的目的则是需要java调用C#生成的dll文件。

       本人涉及dll的封装操作不是很久,暂时未能找到java利用jna调用C#生成的dll的更有效方法,于是采用一种变通的方法。

       这种方法的思路是:c++项目设置为clr公共运行时,可以通过引用的方法调用C#相应方法,java可以通过jna调用c++生成的dll,所以首先需要将C#的dll封装成c++的dll,再通过jna调用封装好的c++的dll文件。

工具:vs2010

首先,生成C#的dll文件。

客户给的dll文件是直接由C#生成的,如果熟悉这dll文件的内部结构则可直接略过此步骤。因为客户给的dll命名空间不够明确,并且其中有两个相似的类,而每个类下又有功能相同且名称相同的几个方法,为了能够明确调用给定的C#的dll动态库文件中的方法,同时为了c++调用方便,这里是将客户给的dll文件利用C#重新封装了一层。步骤如下。

1)     打开vs2010,新建项目,选择C#语言下的“类库”,填写项目名称。

利用jna调用使用C#的dll文件_第1张图片

2)     在生成项目上右击设置项目属性,点击“程序集信息”,勾选“使程序集COM可见”,点击确定。

利用jna调用使用C#的dll文件_第2张图片

3)     设置“生成”属性,勾选“为COM互操作注册”,保存设置。

利用jna调用使用C#的dll文件_第3张图片

4)     在项目的“引用”中添加客户提供的dll文件。

利用jna调用使用C#的dll文件_第4张图片

5)     添加必须的C#代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using QiJuSiChu.SpeechLib;//添加引用的dll名称
namespace PackLib
{
    public class Class1
    {
        acelp_cn_8k lpc8k;  //引用的dll中的算法的实例
        public void dealVoiceToPcm(string voicePath, int curgainshift)
        {
            lpc8k = new acelp_cn_8k();
            lpc8k.Initialize();//初始化
            lpc8k.SetGainShift(curgainshift);//设置增益

            lpc8k.decodeframe(voicePath);//解码

        }
        
    }
}

6)     点击生成项目,成功。



其次,使用c++封装dll文件。

为了能够使用jna调用C#生成的dll文件,必须使用c++进行进行一次封装,这一步骤至关重要。

1)     新建c++项目。

利用jna调用使用C#的dll文件_第5张图片利用jna调用使用C#的dll文件_第6张图片利用jna调用使用C#的dll文件_第7张图片

2)     在项目名称上右击,设置项目属性。

利用jna调用使用C#的dll文件_第8张图片

3)     在项目名称上右击,选择“引用”,引入之前生成的C#的dll。

利用jna调用使用C#的dll文件_第9张图片

4)     添加cpp文件,书写必须的c++代码。代码如下。

#ifdef MYLIBAPI 
#else 
#define  MYLIBAPI  extern "C" __declspec(dllimport)     
#endif 
 
 
MYLIBAPI void DealVoiceToPcm(char *voicePath,int curgainshift); //添加函数声明,此函数为生成的C++的dll的外部公开函数

 
using namespace System;
using namespace PackLib;//添加引入的C#的dll名称

 
void DealVoiceToPcm(char *voicePath,int curgainshift)
{
	String ^ paraStr = gcnew String(voicePath);//需要将char *转换为托管的String类型,否则失败
    Class1 ^method = gcnew Class1();//实例化C#的类
    method->dealVoiceToPcm(paraStr, curgainshift);//调用C#的dll中的方法
    
}

5)     生成项目,成功。

 

最后,需要使用jna引用新生成的C++的dll文件,这与一般的jna调用dll动态库文件的方法一样,不再赘述。

注:这里如果将所有的C#及c++的dll文件放到java项目的目录下,会出现错误,原因是java虽然可以找到c++的dll文件,但是找不到C#的dll文件,需要将C#的dll文件放到运行机器jdk安装目录下的bin文件夹下。问题解决。

再次重复一句这些成的dll文件应当与运行机器上安装的jdk的版本一致(x86或者x64),否则会出现调用出错。






你可能感兴趣的:(dll调用,java编程,C#)