在Windows上使用GCC编译DLL的问题 [英] Problems compiling DLL using GCC on Windows

查看:781
本文介绍了在Windows上使用GCC编译DLL的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MinGW(而不是Cygwin),并试图获得一些我已成功移植到Mac上的OSS代码,在Windows上运行。所需的最终版本是.DLL可用作JNI库(这是Mac上的.jnilib),但编译最后一个.cpp文件时遇到问题。



问题是我的.cpp文件中的每个函数在编译时都会产生以下形式的错误:

  g ++ -I /各种/这样的/条目-D_inline = __ inline -I / c / java / include -I / c / java / include / win32 -c -o com_me_package_ClassName.o com_me_package_ClassName.cpp 
com_me_package_ClassName.cpp:84 :31:错误:符号'void Java_com_me_package_ClassName_Moo(JNIEnv *,jclass)'所需的外部链接,因为'dllexport'属性
//同上面的每个这样的函数
我们来看看上面显示错误的一个函数:

  #include< jni.h> //当然这是在这里
static JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
(JNIEnv * env,jclass clazz){
printf(Moo!\\\
);
}

经过一些Google搜索之后,我看到别人有一个项目, 功能是一个问题,所以我尝试在创建错误的任何功能之前添加以下hack到.cpp文件:

  #ifdef WIN32 
#define static
#endif

然而,while这解决了编译问题,它只让我遇到一个连接问题,这可能是也可能不是ifdef权限的结果(可能只是与破坏):每个基于C的基础功能都丢失,即使它们可以从-L指定的静态库(如FOO_int2str)在Mac构建中可靠地找到,如下所示:

  g ++ -D_inline = __ inline -shared -o /output/lib/libfoo_jni.dll com_me_package_ClassName.o -L / some / number / of / such / something -lz -lzipfile 
com_me_package_ClassName.o:com_me_package_ClassName.cpp :(。text + 0x84 ):未定义的引用`_imp__F OO_int2str'

我有一点损失。通过Google找到的大部分事情与其他构建环境(例如,cygwin和Microsoft提供的编译器)具有相当重要的环境关系。我有gcc和MinGW,并希望避免与dlltool或Cygwin这样的问题相关的答案,因为我正在工作的代码已经通过了很多手,并且在其中有黑暗的魔法(如语音识别),就像笼罩的闪电。 ..我越来越多的风险,我运行的Mac平台上的现有功能将消失。



我是一个新手在makefile写作。我现在有这个建筑是一个幸福的意外,因为这个代码是从一个巨大的语料库中提取出来的,这个语料库用的是非常重的构建,而不是桌面平台,一个构建环境,我知道我不得不倾倒,我已经成功地完成了(至少对于Mac)。有没有返回那里!



提前感谢任何建议,显式的命令行调用到g ++(或类似gcc的等效),这将使这些函数编译和链接。



解决方案

你不想让你的功能 static 因为这给他们内部链接。错误信息告诉您,这与导出的功能不兼容。您的JNI功能需要具有外部链接。这可以通过用 extern 替换 static 来实现。但是,由于外部链接是函数的默认值,您可以简单地删除 static 链接说明符,省略 extern 。 p>

您还需要指定C连接,因为您正在编译为C ++而不是C。使用 externC 。如果使用默认的C ++连接,那么最终会出现C ++名称的错误,我猜想是链接器错误的原因。



所以你的代码应该是这样的: / p>

  #include< jni.h> 

externC
{

JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
(JNIEnv * env,jclass clazz)
{
的printf( 哞\\\
!);
}

}


I am using MinGW (not Cygwin) and trying to get some OSS code which I have successfully ported to the Mac to run on Windows. The desired final build is a .DLL usable as a JNI library (this is a .jnilib on the Mac), but I am having trouble compiling the last .cpp file which wraps the interface.

The issue is that every function in my .cpp file generates an error in the following form upon compilation:

g++ -I/various/such/entries -D_inline=__inline -I/c/java/include -I/c/java/include/win32 -c -o com_me_package_ClassName.o com_me_package_ClassName.cpp
com_me_package_ClassName.cpp:84:31: error: external linkage required for symbol 'void Java_com_me_package_ClassName_Moo(JNIEnv*, jclass)' because of 'dllexport' attribute
// ditto the above for every such function

Let's look at the one function whose error is shown above:

#include <jni.h> // of course this is in here
static JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
    (JNIEnv *env, jclass clazz) {
printf("Moo!\n");
}

After some Googling of this, I saw someone else had a project where "static" functions were an issue, so I tried adding the following hack to the .cpp file before any of the functions that created the error:

#ifdef WIN32
#define static 
#endif

However, while this solved the compilation issue, it only got me to an issue in linking which may or may not be a result of the ifdef expedient ( and which may well have only to do with mangling): every C-based underpinning function went missing even though they were reliably found in the Mac build from the -L specified static libraries, such as FOO_int2str as shown here:

g++ -D_inline=__inline -shared -o /output/lib/libfoo_jni.dll   com_me_package_ClassName.o -L/some/number/of/such/things -lz -lzipfile
com_me_package_ClassName.o:com_me_package_ClassName.cpp:(.text+0x84) : undefined reference to `_imp__FOO_int2str'

I'm at a bit of a loss. Most of the few things I find via Google have fairly heavy contextual ties to other build environments (cygwin and Microsoft-supplied compilers, for instance). I have gcc and MinGW and would like to avoid answers that tie to things like dlltool or Cygwin, as the code I am working in has passed through many hands and has dark magicks (such as speech recognition) within it that are like caged lightning... the more I change the more risk I run that existing function on the mac platform will vanish.

I am a neophyte at makefile writing. That I have this building at all at the moment is a happy accident, as the code was extracted from a gigabytes-large corpus with a very heavy build gestalt targeting mobile rather than desktop platforms; a build context I knew I had to dump and which I've done so successfully (for the Mac at least). There's no going back there!

Thanks in advance for any advice with explicit command-line invocations to g++ (or gcc-like equivalent) that will get these functions to compile and link.

tone

解决方案

You don't want to make your functions static because that gives them internal linkage. As the error message tells you, that's not compatible with the functions being exported. Your JNI functions need to have external linkage. This can be achieved by replacing static with extern. However, since external linkage is the default for functions you can simply remove the static linkage specifier and omit extern.

You also need to specify C linkage since you are compiling as C++ rather than C. Do this with extern "C". If you use the default C++ linkage then you end up with C++ name mangling which I suspect is the cause of your linker error.

So your code should be like this:

#include <jni.h> 

extern "C"
{

JNIEXPORT void JNICALL Java_com_me_package_ClassName_Moo
    (JNIEnv *env, jclass clazz) 
{
    printf("Moo!\n");
}

}

这篇关于在Windows上使用GCC编译DLL的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆