求助,C++调用一个原本用于java程序的dll文件

清蒸葡萄糖 2017-07-28 08:50:48
简单点来说的话,我在使用C++调用一个原本用于java程序的dll文件时,总是被bad_alloc踢出来。
复杂点说的话.....
/***********************************/
现在想要提取一个java程序里面的算法函数原理,用于C++编程。
目标是找到它的算法原代码或者能够让我用黑箱子调用它都可以。
首先用zip对exe进行解压,然后反编译了一个关键class文件,得到目标java函数:
public native short function1(byte[] para1,int para2);

看到native便开始准备黑箱子调用。

用dumpbin.exe处理了与之相关的DLL文件,得到:
1 0 00005910 Java_function1
我没有这个dll文件的源码,没有h、pdb、lib文件,仅有一个dll。
只知道它本来是供java程序使用,不知道此dll由什么语言写成。
/***********************************/
我的C++环境是VS2015,把dll文件放进cpp文件所在目录,然后尝试动态调用它:

#include<Windows.h>
#include<iostream>
using namespace std;
typedef short (*fit_type)(char[], int);
int main()
{
const char* dllName = "resource_x64.dll";
const char* funName1 = "Java_function1";
char seq1[] = "seq1";
HMODULE hDLL = LoadLibrary(dllName);
if (hDLL != NULL)
{
fit_type function1 = fit_type(GetProcAddress(hDLL, funName1));
if (function1 != NULL)
{
cout << "test start!" << endl;
cout << function1(seq1, 0)<<endl;
}
else
{
std::cout << "Cannot Find Function " << funName1 << std::endl;
}
FreeLibrary(hDLL);
}
else
{
std::cout << "Cannot Find " << dllName << std::endl;
}
return 0;
}

在32位debug下找不到dll文件。
在64位debug下,"test start!"输出到了屏幕上,紧接着在function1被调用的那一行因bad_alloc而被踢了出来。
首先认为可能是数据类型问题。
我尝试了把int改成short,把char改成unsigned char,加上__stdcall,更改seq1的定义方式为char* seq1="seq1"等等众多方法,改过来改过去各种组合,都没有解决问题。
可能是思考方向有问题,研究的方向不太对,但又不知道问题出在哪里,只能继续摸索。
/***********************************/
动态没成功,我想切换静态方法尝试一下:
首先用dumpbin.exe得到dll的export信息,然后修改为ref格式,然后用lib.exe制成lib文件,和dll一起放在cpp文件所在目录。
然后在cpp中写下以下代码,尝试静态调用:

#include<Windows.h>
#include<iostream>
using namespace std;
#pragma comment (lib,"resource_x64.lib")
extern short Java_function1(char seq[], int num);
int main()
{
char seq1[] = "seq1";
cout << "test start!" << endl;
cout << Java_function1(seq1,0)<<endl;
return 0;
}

编译结果:
error LNK2019: 无法解析的外部符号
fatal error LNK1120: 1 个无法解析的外部命令

替换第二行。
extern "C" __declspec(dllexport) short Java_function1(char seq[], int num);

运行结果:
输出了"test start!",然后在Java_function1被调用的那一行因bad_alloc而被踢了出来。
是不是说明这个dll是用C写成的?

修改倒数第二行为
Java_function1("seq1",0);

依然因bad_alloc而被踢了出来。

再改:这次用new来分配内存

#include<Windows.h>
#include<iostream>
using namespace std;
#pragma comment (lib,"resource_x64.lib")
extern short Java_function1(char seq[], int num);
int main()
{
char* seq1 = new char[5];
seq1 = "seq1\0";
cout << "test start!" << endl;
cout << Java_function1(seq1,0)<<endl;
return 0;
}

依然因bad_alloc而被踢了出来。
/***********************************/
无果,决定反汇编/反编译。
ildasm和Reflector都提示这不是.NET,无法反汇编/反编译
考虑过使用java来调用这个dll,然后用C++通过JNI调用java。
不过这样效率是不是有些低?C++模块中存在多线程部分,而且比较要求性能。
我不知道Java_function1中是否存在修改seq1的行为。
/***********************************/
综上:
我三天来的自行思考过程都在上面了,实在没想到好的解决办法。
我的目标是想要提取这个java程序里面的算法函数原理,用于C++编程,无论是找到它的算法原代码或者能够让我用黑箱子调用它都可以。
谢谢~
...全文
229 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Zeroonezeroone 2017-11-06
  • 打赏
  • 举报
回复
怎么样,我也遇到和你类似的问题,我的是只有dll和lib文件而没有h文件。显示的结果也是:无法解析外部符号-》Unresolved Externals???求解,或者是大神点拨一二,,,,万分感谢
santan 2017-07-29
  • 打赏
  • 举报
回复
第二个参数不用0试一下.
清蒸葡萄糖 2017-07-29
  • 打赏
  • 举报
回复
原先java里面所有调用都用的0,并不知道有什么含义。直觉认为还是不要改的好…… 好的我去试试depends、DLL Export Viewer和IDA Pro。 程序要移动到其他电脑运行。如果要把C++、JNI和java运行时库都安装才能用,可能不是上策。如果其他方法不行会试试的。 谢谢~ 估计要过段时间才能回来发进一步测试结果。
encoderlee 版主 2017-07-29
  • 打赏
  • 举报
回复
如果这个DLL是专为JNI调用设计的
public native short function1(byte[] para1,int para2);
这个函数在dll的c代码中,肯定不止这两个参数,还有JNIEnv * env等参数
了解一下JNI的相关知识
使用Depends和DLL Export Viewer等工具查看一下dll导出函数的原型
也可以用IDA Pro反编译一下这个dll,按F5查看dll函数的C伪代码,弄清楚函数的形状

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧