围绕C++方法编写一个JNI包装器
Write a JNI wrapper around a C++ method
我有三个C++文件,我想在Android工作室中使用。
- 页眉.h
- A.cpp(包含主方法+其他方法)
- B.cpp
我已将它们编译成一个静态库。现在,我想围绕C++方法编写JNI包装器,并将其调用到java部分。到目前为止,这是我的包装:
#include <jni.h>
#include <string.h>
#include <stdlib.h>
extern "C" {
JNIEXPORT int JNICALL Java_cgi_pi_detect(? ,?) {
IplImage * byteQueryImage = loadByteImage ( ? );
if ( !byteQueryImage )
{
printf ( "couldn't load query imagen" );
return -1;
}
// Detect text in the image
IplImage * output = textDetection ( byteQueryImage, atoi(1));
cvReleaseImage ( &byteQueryImage );
cvSaveImage ( ? , output );
cvReleaseImage ( &output );
return 0;
}
}
我想给它两张图片作为参数:一张加载IplImage * byteQueryImage = loadByteImage ( ? );
,另一张保存cvSaveImage ( ? , output );
。这两个参数的jni类型JNIEXPORT int JNICALL Java_cgi_pi_detect(? ,?)
应该是什么(如果我认为图片是.png)?
这样调用main()
充满了危险将调用哪个main()
?JVM可执行文件还有一个main()
。(是的,我忽略了"未定义的行为",因为问题是如何使其发挥作用。)
要获得所需的main()
,最困难的方法是将其编译成一个共享对象,加载该共享对象,并通过使用dlopen()
和dlsym()
的运行时动态链接在该共享对象中自己找到main()
(省略错误检查):
#include <dlfcn.h>
...
// use a typedef for the function pointer
typedef int ( *main_func_t )( int, char ** );
...
// Handle to your .so with your "main()" in it
// make them static so they're only loaded once
static void *libHandle = NULL;
static main_func_t libMain = NULL;
if ( NULL == libHandle )
{
libHandle = dlopen( "yourLibName.so", RTLD_NOW );
libMain = ( main_func_t ) dlsym( libHandle, "main" );
}
...
// now call the main() in that library
int mainRetVal = libMain( argc, argv );
...
因此,这意味着您需要两个共享对象:第一个"普通"对象用于保存您的JNI调用,第二个对象用于保存要调用的"main()"。第一个"普通"JNI库需要使用-ldl
链接器参数与libdl.so
的依赖项进行链接。
简单的方法?
将要调用的main()
重命名为其他对象,并将其放入普通的JNI共享对象中。然后直接调用它——它不再被称为main()
,因此不再有任何名称冲突。
即便如此,我怀疑您仍然可能遇到问题——名称冲突或不兼容的库会立即出现在脑海中。
是否更容易工作?
在子流程中运行它,因为这是它的运行方式,而且它实际上是一个黑盒:你用参数调用它,它做任何事情,然后你得到一个int
返回值。函数调用或子流程也是如此。
您可以将包装函数放在任何将要编译的文件中,无论是新文件还是现有文件。与Java不同,在C++中,文件名对编译器没有任何意义。
如果您不打算独立于Java调用其他方法,则不需要包装它们。
PS:请注意,包装器函数的名称Java_cgi_pi_detect
源自定义此detect
本机方法的Java类。使用javah
工具生成实现本机Java方法的C函数的正确名称。
- JNI,使用两个 .so 文件时出错,其中一个文件需要另一个文件
- 我正在尝试修改一个字节数组并通过 JNI 将其从 c++ 发送到 java
- Java加载DLL,该DLL从JNI中的另一个DLL导出方法
- 我可以创建一个JNI调用以提升从Java的C 光纤
- Android Studio使用JNI来构建C/C ,但是C/C 需要另一个lib.a,如何解决
- 用C++为java构建一个dll,它正在调用另一个dll(Eclipse上的JNI)
- 从 ndk 中的 jni 方法调用另一个C++方法
- JNI和另一个线程出现ArrayStoreException错误
- 使用JNI调用API创建一个java7JVM
- JNI 中的 Java 线程C++仅使用一个内核的环境.Arm 处理器和 Ubuntu
- 你能不能使用 JNI 在从 java 调用的 c++ 函数中创建一个新的 JVM
- JNI - 创建另一个C++类的实例
- 围绕C++方法编写一个JNI包装器
- 如何使JNI项目在所有JB、KK和LP下工作,这些项目仅在一个平台下编译
- 在C++中创建一个字节[][],并使用JNI将其返回给Java
- 制作一个供JNI读取的Android Studio JNI静态库
- 如何部署一个混合的C++/Java(JNI)应用程序
- 另一个 JNI、C++、DLL、UnsatisfiedLinkError <Native Method>
- 使用JNI加载另一个JNI库
- 一个JNI错误出现在quick cocos中