jna调用c++的动态库

       用Intellij idea来编写java程序,关于如何在java中调用现有的dll库,先关键字"jna"搜索到github上的"java-native-access/jna"项目,然后参考了csdn上的文章<JNA—JNI终结者>,这篇文章先"下载jna.jar"然后在JNA例子中的"在Java项目中引入jna.jar包",然后就关键字"intellig idea jna.jar"搜索到文章< IntelliJ IDEA java项目中添加jar包_百度经验>,即如何在intellij idea中导入jar文件。

       参考了csdn上的文章<Java通过JNA方式调用DLL>,将生成的动态库直接放到idea工程的src目录下(即跟xxx.iml平级的目录下的src文件夹下),然后报错"Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'add': 找不到指定的程序。",看起来像是库中的函数并没有被导出来,结合前面搜索到csdn文章<java使用JNA调用dll踩的坑>,添加"extern "C" __declspec(dllimport)"修饰符后不再报错。不过这篇文章中说需要把生成的dll放到jdk的bin目录下:"这里首先需要将上图倒数第三行路径下的DLL文件放入jdk的bin文件夹中"。

       后面又报错"Exception in thread "main" java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。",参考了文章<关于JAVA调用C++的几种方式和一些问题 UnsatisfiedLinkError>:"请注意你的C++编译版本要和JDK的编译版本一致,一般情况下要么需要编译32位的,要么是64位的",然后重新用visual studio编译了x64版本release版本dll就成功了。

       如果idea工程的src目录下(即跟xxx.iml平级的目录下的src文件夹下)没有发现所load的dll库,则会报错"Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'xxx':找不到指定的模块。"。如果报错"Exception in thread "main" java.lang.UnsatisfiedLinkError: 找不到指定的模块。",那么说明xxx这个dll是存在的,但是很有可能是xxx这个dll依赖了yyy这个dll,而yyy这个dll并没有跟xxx这个dll放到一起,即路径下并没有包含xxx这个dll依赖的子dll,放到一起就好了。

       在jni的上一级目录中执行ndk-build编译jni,报错"jni/armeabi-v7a/include/protobuf/google/protobuf/generated_message_reflection.h:709:31: error: 'dynamic_cast' not permitted with -fno-rtti",然后需要在jni/Application.mk加上一行"APP_CPPFLAGS := -frtti -std=c++11"就可以了,其中frtti表示Enables support for run-time type information (RTTI),-std=c++11表示支持c++新标准。

        在用ndk-build来编译时,需要先cmd命令行窗口到app\src\main目录下,然后执行ndk-build -j8(表示8核处理,也可以不要该参数),该目录下包含了jni目录,然后生成了跟jni目录平行的libs、obj目录,libs和obj\local目录下分别包含arm64-v8a、armeabi-v7a、x86、x86_64目录。

         后面想只生成armeabi-v7a平台的库,然后在jni目录下加了Application.mk,结果ndk-build报错"Android NDK: android-9 is unsupported. Using minimum supported version android-16",然后就修改Application.mk文件"APP_PLATFORM := android-16",结果报警告"Android NDK: WARNING: APP_PLATFORM android-16 is higher than android:minSdkVersion 1 in ./AndroidManifest.xml. NDK binaries will *not* be compatible with devices older than android-16.",因为app目录下的build.gradle中是"compileSdkVersion 29 minSdkVersion 23 targetSdkVersion 29",所以修改Application.mk文件"APP_PLATFORM := android-23",结果还是报警告"Android NDK: WARNING: APP_PLATFORM android-23 is higher than android:minSdkVersion 1 in ./AndroidManifest.xml. NDK binaries will *not* be compatible with devices older than android-23."。之前Application.mk文件包含"APP_STL := gnustl_shared",结果报错"D:/AndroidStudio/Android/Sdk/ndk-bundle/build//../build/core/add-application.mk:178: *** Android NDK: APP_STL gnustl_shared is no longer supported. Please switch to either c++_static or c++_shared. See https://developer.android.com/ndk/guides/cpp-support.html for more information.    .  Stop.",然后就修改Application.mk文件包含"APP_STL := c++_shared",然后Application.mk文件包含"APP_ABI := armeabi-v7a"就只生成了armeabi-v7a平台的so库文件。

         Android.mk文件的LOCAL_C_INCLUDES指定了包含的头文件路径,可以参考gaminganywhere的书写方式。关于怎么根据*.java文件生成对应的jni头文件,关键字"jni -h"搜索到文章<JNI中javah命令的使用,生成.h的头文件>,说需要先有.class文件,然后调用"javah -classpath ."命令,实际上只用cmd到XXX\src\main\java目录下,然后执行"javah -jni 包名.类文件名"就可以在当前目录下生成jni对应的头文件了。

          sourcetree_2.5.5.0

        编译live555的vs2013版本库文件,参考了文章<LIVE555简介及在Windows上通过VS2013编译操作步骤>,然后编译得到x64平台的库文件,注意参数(COMPILE_OPTS --->/EHsc /O2 /MT /GS /D "WIN64" /Oy- /Oi /D "NDEBUG")。后面想编译win32平台的库文件,也是修改了win32config文件,只是修改了TOOLS32参数的值,注意参考文章<Windows下编译live555>(关键字:fatal error U1052: 未找到文件“ntwin32.mak”搜索到简书上该篇文章,该文章指出如何编译debug和md/mt运行库版本:"如果要编译可调试的debug版本静态库,先把win32config文件中的第二行“NODEBUG=1”注释掉。如果想将c运行库从多线程DLL(/MD)改成多线程(/MT),需要修改win32config文件中COMPILE_OPTS选项"),打开C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts目录下的"VS2013 开发人员命令提示",一开始搞错了,管理员运行的是"VS2013 x64 本机工具命令提示",导致报错"。后面想编译vs2019版本的32位的live555,然后google关键字"live555 vs2019"搜索到文章<Build Live555 with Visual Studio 2019 - 3735943886>,同样是修改win32config文件:(TOOLS32 = "C:\Program Files\Microsoft Visual Studio\2019\[Community, Express, BuildTools, or etc.]\VC\Tools\MSVC\[VERSION, 14.22.27905 for example]\;C_COMPILER = "$(TOOLS32)\bin\hostx86\x86\cl"),不过并没有修改(LINKER = "$(TOOLS32)\bin\hostx86\x86\link"),然后就直接nmake构建,也报错(fatal error U1052: 未找到文件“ntwin32.mak”),然后同样按照之前的文章<Windows下编译live555>拷贝了NtWin32.Mak、Win32.Mak到C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include目录下,然后启动C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC目录下的“x86 Native Tools Command Prompt for VS 2019”构建成功。

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\crtdefs.h(494) : error C2371: “size_t”: 重定义;不同的基类型
        predefined C++ types (compiler internal)(19) : 参见“size_t”的声明

C:\Program Files (x86)\Windows Kits\8.1\include\um\winnt.h(19834) : error C3861: “__readfsdword”:  找不到标识符

C:\Program Files (x86)\Windows Kits\8.1\include\um\winbase.h(8828) : error C3861: “_InterlockedIncrement”:  找不到标识符

C:\Program Files (x86)\Windows Kits\8.1\include\um\winbase.h(8848) : error C3861: “_InterlockedIncrement64”:  找不到标识符"。

        保存的264裸流用"Elecard StreamEye Tools"下的eseye_u.exe工具播放时候报错"Can't open the file. Media file:xxx Index file:xxx"后面参考了rtspclient.cpp里面保存裸流的流程,注意加上头部信息就可以了。后来参考,在"gaminganywhere-master\ga\module\encoder-video\encoder-video.cpp"文件中保存服务端发送的裸流也是一样的问题,打印h264or5_get_vparam函数的前面字节数,保存成二进程文件后,cat命令将其拼接到纯264裸流的头部后就可以正常播放了。   

        live555官网上给的是最新版本的下载包,想下载个旧的版本,google关键字"live555 xxxx.xx.xx"搜到网址"mirror.sobukus.de/files/src/live555/?C=N;O=D",然后就可以下载了,用by对比文件夹就可以知道live555的当前版本号。

        用最新版的protobuf来构建android的so库文件,先关键字"protobuf ndk"搜到文章<protobuf使用(一)android ndk 编译 protobuf-3.6.x windows>,然后参照着编译得到libprotobuf.a文件。然后再去编译网络库的时候报错(error: undefined reference to 'typeinfo for std::__1::ios_base'),关键字搜索到文章<android studio build报错error: undefined reference to 'std::>,"意思是说gnustl过时了,应该用c++_shared",然后替换成c++_shared就果然正常编译通过了。live555依赖顺序"liveMedia groupsock BasicUsageEnvironment UsageEnvironment",顺序错误可能导致"error: undefined reference to xxx"错误。参考了gaminganywhere-master里面的Android编译流程,Android.mk文件里包含了"include jni/Android.prebuilt",子文件里包含了"LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libxxx.a",如果不包含这个依赖项也会包"error: undefined reference to xxx"错误。

        关于报错"Segmentation fault (core dumped)",查看了文章<Linux下gdb调试生成core文件并调试core文件>:"有问题的程序运行后,产生“段错误 (核心已转储)”时生成的具有堆栈信息和调试信息的文件。编译时需要加 -g 选项使程序生成调试信息",注意"ulimit -c unlimited"用来配置生成core文件,"gdb [exec file] [core file] 然后执行bt看堆栈信息"即可查看出错位置。直接"man strftime"并运行g++后得到的例子就出现了段错误,然后最终分析是并没有传入表示时间格式的参数导致的。

        live555的mediaServer工程运行起来后,明确打印支持的本地文件格式是.264、.265、.aac……等,但是并不支持mp4格式的,但是支持.mkv格式文件。

        参考了文章<第一个NDK-JNI项目>和JniDemo(com.example.jnidemo.jnitest.JniTest),文章说"build project 得到中间文件.class,路径:app\build\intermediates\classes\debug",但是用android studio4.0测试发现生成在app\build\intermediates\javac\debug\classes\com\example\jnidemo\jnitest目录下,而且需要进到app\build\intermediates\javac\debug\classes目录下执行"javah -jni com.example.jnidemo.jnitest.JniTest"就可以在当前目录下生成对应的头文件com_example_jnidemo_jnitest_JniTest.h了。

        android studio同步的时候报错"Failed to find Build Tools revision 26.0.2 Install Build Tools 26.0.2 and sync project
Upgrade plugin to version 4.0.0 and sync project",然后修改根目录下的build.gradle文件,将buildscript下的dependencies子项的classpath从3.0.0升级为 classpath 'com.android.tools.build:gradle:3.5.2'即可。文章<NDK开发第一课:环境配置与第一个JNI程序>在步骤"手动配置  gradle 支持 NDK 开发"指出"要手动配置 Gradle 以关联到您的原生库,需要将 externalNativeBuild {} 块添加到模块级 build.gradle 文件中,并使用 cmake {} 或 ndkBuild {} 对其进行配置"。而且还要注意"如果您想要将 Gradle 关联到现有 ndk-build 项目,请使用 ndkBuild {} 块而不是 cmake {},并提供Android.mk文件的相对路径。如果 Application.mk 文件与您的 Android.mk 文件位于相同目录下,Gradle 也会包含此文件"。

        参考JniDemo工程,因为app\src\main\jni目录下的Application.mk文件中"APP_ABI := all"指定了全平台,所以在app\src\main目录下包含jniLibs目录,包含了"arm64-v8a/  armeabi-v7a/  x86/  x86_64/"目录,里面存放了对应的so库文件。windows平台cmd窗口到app\src\main目录下(即包含了Android.mk文件的jni目录的上一级目录),然后执行ndk-build命令就会在该目录下生成libs目录,里面包含了对应平台的库文件。如果把app\src\main目录下的jniLibs目录删除,则apk运行过程中会由于找不到so库崩溃,参考文章<Android关于libs,jniLibs库的基本使用说明及冲突解决>的"比如要集成第三方NDK库,Android Studio中,则会默认匹配main下的jniLibs目录,如果没有目录需要自己手动创建",所以"想用libs下的库,还需要手动去指定库的位置",文章libs是跟src平级的,而JniDemo工程中ndk-build命令生成的是src\main目录下,对应的在app目录下的build.gradle文件中sourceSets子项-main子项指定"jniLibs.srcDirs = ["src/main/libs"];",然后再构建并运行工程就不会崩溃了,可以参考文章<Android NDK开发,使用ndk-build编译>有更详细的ndk使用方法。在文章<用ndk-build编译NDK程序>说明"默认情况下,ndk-build使用libstdc++,如果要使用c++_shared,可以在Application.mk中,使用APP_STL变量指定",并介绍了"Android使用的C++库",用"ndk-build NDK_LOG=1"可以"指定选项 NDK_LOG=1 可以看ndk-build执行的具体过程。如使用哪个编译器,使用了哪个标准库,等等"。新的方法是用CMakeLists.txt,不再用Android.mk文件了。文章<CMakeLists.txt 语法介绍与实例演练>里介绍了部分使用规则。

        同步工程报错"Cause: executing external native build for cmake F:\refAndroid\NDKLearnDemo-master\app\CMakeLists.txt",这是因为app\CMakeLists.txt这个文件出错了,原本NDKLearnDemo工程是app\CMakeLists.txt包含了ADD_SUBDIRECTORY(src/main/cpp/one)、ADD_SUBDIRECTORY(src/main/cpp/two),但是把src\main\cpp目录下的one、two两个文件夹全删掉了,然后同步就报上面这个错误。

        执行"go get github.com/fogleman/nes"命令,得到错误"# pkg-config --cflags  -- portaudio-2.0 Package portaudio-2.0 was not found in the pkg-config search path. Perhaps you should add the directory containing `portaudio-2.0.pc' to the PKG_CONFIG_PATH environment variable No package 'portaudio-2.0' found pkg-config: exit status 1",搜到文章<Building the portaudio golang wrapper on Windows>指出"then install mingw-w64-x86_64-portaudio",关键字"mingw-w64-x86_64-portaudio"搜到文章(https://packages.msys2.org/package/mingw-w64-x86_64-portaudio)指出"Installation: pacman -S mingw-w64-x86_64-portaudio",然后在cmd窗口执行命令安装成功。pacman.exe在C:\msys64\usr\bin目录下,然后再执行"go get github.com/fogleman/nes"成功。

        std::future提供了一个访问异步操作结果的机制,它和线程是一个级别的属于低层次的对象,在它之上高一层的是std::packaged_task和std::promise,他们内部都有future以便访问异步操作结果,std::packaged_task包装的是一个异步操作,而std::promise包装的是一个值,都是为了方便异步操作的,因为有时我需要获取线程中的某个值,这时就用std::promise,而有时我需要获一个异步操作的返回值,这时就用std::packaged_task。

        std::async是为了让用户的少费点脑子的,它让这三个对象默契的工作。大概的工作过程是这样的:std::async先将异步操作用std::packaged_task包装起来,然后将异步操作的结果放到std::promise中,这个过程就是创造未来的过程。外面再通过future.get/wait来获取这个未来的结果,怎么样,std::async真的是来帮忙的吧,你不用再想到底该怎么用std::future、std::promise和std::packaged_task了,std::async已经帮你搞定一切了!

        参考文章<C++ 函数模板特化导致的多重定义链接错误>,"函数模板,一般都是放在头文件里面,所以有些时候,我也会做一个特化,也放在这个头文件里面,当这个头文件出现多次的包含之后,就会出现链接多重定义的错误"。这是因为"因为特化后的函数就是一个普通函数,这个和在一个头文件里面定义一个函数,然后多出include这个头文件一样的结果,都会导致多重定义"。解决办法"把特化的函数,添加inline标记,这样,编译器不会给这个函数生成一个函数符号,就当作是一个宏展开;利用static让这个函数成为文件域,也就是不参与全局link,也是可以的(个人注释:也就是直接将前面的inline替换成static,用vs2019测试好像并不行(不要在模板头文件中已经添加了模板的实现,然后再该模板头文件中再加上static修饰的特化版本,这样会重定义,但是inline是替换还是可以的));还有一个办法就是,把这个特化从头文件里面拿出去,放在需要的实现文件里面,再添加static属性(个人注释:貌似如果直接在所有需要用到的cpp文件里直接导入模板的实现并不会发生重定义)"。

        参考文章<C++继承中的同名覆盖>:"继承父类成员函数,累加父类的同名成员";"子类可以定义父类中的同名成员,子类中的成员将隐藏父类中的同名成员,编译器认为已经从父类中继承得到这个成员了,又自定义了一个同名成员,目的只有一个,就是你想要自己自定义的同名成员、而不想要从父类那里继承得到的同名成员,因此会产生同名覆盖现象,父类中的同名成员依然存在于子类中,是隐藏而不是销毁,通过作用域分辨符(::)访问父类中的同名成员";"函数重载必须发生在同一个作用域中";"子类可以定义父类中完全相同的成员函数,子类中的函数将隐藏父类的同名函数,子类无法重载父类中的成员函数,因为它们处于不同的作用域;使用作用域分辨符访问父类中的同名函数:类名加上作用域分辨符";"子类中的成员将隐藏父类中的同名成员,包括同名成员变量和同名成员函数"。

        关于grpc的使用搜到csdn文章<gRPC笔记1:Windows系统C++语言编译gRPC>,跟文章不一样的是用cmake的界面客户端生成vs工程文件,而不是用命令生成,然后"找到INSTALL项目",注意"如果遇到权限错误,使用管理员方式打开,重新执行","生成的文件路径:C:\Program Files (x86)\grpc"。可以将此目录拷贝到其他文件夹下,然后生成的xxx.pb.cc单独编译没有问题,但是xxx.grpc.pb.cc报错"error C2059: 语法错误:“public”",但是该行"class AliyunOss final {"的前面是一行注释"// 服务端定义",把注释屏蔽掉后就不会报错了,后来发现这个注释是proto文件中的注释,然后在这个注释后面留一个空格,然后再生成的xxx.grpc.pb.cc编译就不会报错了。之前报错后并不清楚为什么,就去grpc的目录下找了一个proto来测试,排除了是生成pb文件的proto.exe及grpc_cpp_plugin.exe的问题,后面才发现是中文注释的问题。在文章<编译gRPC(windows)和测试demo>中指出为解决链接错误需要链接"gpr.lib grpc.lib grpc++.lib libprotobuf.lib"库。

        想生成xxx.proto文件go版本pb文件,先参照了<Windows下protoc-gen-go的使用方法(goprotobuf)>这个早期版本(这篇文章过时,不用再参考了),还要配置protoc-gen-go.exe;后面参照了博客园上的 <golang gRPC 入门>,"安装 protoc go 插件"执行后就在$GOPATH/bin的目录下得到protoc-gen-go.exe文件,然后调用protoc可执行文件(依照文章的示例,protoc --go_out=plugins=grpc:. xxx.proto)生成相应的pb文件(如果报错"拒绝访问。--go_out: protoc-gen-go: Plugin failed with status code 1.",则可能是前面的$GOPATH/bin的目录下并未包含正确的protoc-gen-go.exe文件),发现除了完全包含早期版本生成的pb文件的全部内容,还比早期版本多了grpc、codes、status导入包内容。

        关于govendor的使用,先参考了简书上的文章<使用govendor管理包依赖>,注意在执行初始化"govendor init"命令后,会提示目录必须在GOPATH指定的路径上,在执行"从GOPATH添加依赖包到vendor目录"步骤后,并没有"发现vendor.json文件里多了依赖包的信息,vendor目录下多了依赖包"。后来又搜到csdn上的文章<使用govendor管理Golang项目依赖>,该文章参考了推酷上的文章<使用vendor管理Golang项目依赖>,不过示例中导入的"github.com/yeeuu/echoic"已经被移除了,已经从github上下架了,所以就参考了falcon的vendor/vendor.json文件,然后在目录下新建go文件,并导入"github.com/mindprince/gonvml",然后再执行"从GOPATH添加依赖包到vendor目录"步骤,就可以"发现vendor.json文件里多了依赖包的信息,vendor目录下多了依赖包"。如果在当前目录下再新建go文件,然后导入不同的包,则再执行"从GOPATH添加依赖包到vendor目录"步骤,就会发现vendor.json文件里多了新的依赖包的信息。vendor/vendor.json文件中可能出现递归的导入依赖包信息。vscode并不支持vendor,但是可以在命令行下直接go run执行。

        关于"go mod"的使用,参考了简书上的文章<go mod使用>,首先调用"go env -w"设置GO111MODULE、GOPROXY,然后就直接参照"使用go mod管理一个新项目",一开始GOPROXY设置成阿里云的goproxy:http://mirrors.aliyun.com/goproxy/,结果go run xxx.go时候报错"build command-line-arguments: cannot load xxx: cannot find module providing package xxx",然后关键字"build command-line-arguments: cannot load  cannot find module providing package"搜索到博客园上的文章<go mod 无法自动下载依赖包的问题>,文章说"git版本太低了,无法支撑go get运行git时的参数调用",后面升级了ubuntu的git,但是还是报同样的错误,然后按照之前的文章<go mod使用>,设置GOPROXY:"go env -w GOPROXY=https://goproxy.cn,direct // 使用七牛云的",然后再次go run xxx.go就不再报错了。

        生成proto文件对应的c++文件时候报错"Import "google/api/annotations.proto" was not found or had errors.",然后关键字"c++ google/api/annotations.proto"搜索到https://github.com/grpc-ecosystem/grpc-gateway/issues/574,然后参考了其写法,先把github.com/grpc-ecosystem/grpc-gateway下载到GOPATH目录下,然后加上"-I%GOPATH%\src\github.com\grpc-ecosystem\grpc-gateway\third_party\googleapis"就不再报错了。

        想跨平台编译github上工程pytorch/cpuinfo的ios版本,然后就关键字"ios cmake"搜到github上工程leetal/ios-cmake,然后参照步骤执行"cmake ../../../ios.toolchain.cmake xxx"后报错'deps/googlebenchmark/CMakeLists.txt "Failed to determine the source files for the regular expression backend"',然后看了下是regex的原因,然后在执行cmake的时候加上-DRUN_HAVE_STD_REGEX=0,结果又报错"INSTALL TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable"。然后参照着pytorch/cpuinfo的issue"Instructions for building for iOS? #6",用"libfreetype2/freetype2/builds/cmake/iOS.cmake"编译成功,不过并没有"set(IOS_ARCH i386)修改为set(IOS_ARCH "i386 x86_64")" ,然后参照"github.com/leetal/ios-cmake"执行"cmake --build . --config Release --target install"生产.a库文件。编译得到的.a文件防止iphone上报错(Undefined symbols for architecture arm64:"_cpuinfo_arm_mach_init", referenced from:  _cpuinfo_initialize in libcpuinfo.a(init.o)),然后查看了cpuinfo_arm_mach_init函数在src\arm\mach\init.c文件中,而CMakeLists.txt文件中,包含了"LIST(APPEND CPUINFO_SRCS src/arm/mach/init.c)"的父分支是"ELSEIF(IOS)",并且iOS.cmake文件中"set(IOS True)",但是其祖父分支的判断"ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv[5-8].*|aarch64)$" OR IOS_ARCH MATCHES "^(armv7.*|arm64.*)$")"不成立,可以通过在CMakeLists.txt文件调用MESSAGE输出日志查看。然后关键字"CMAKE_SYSTEM_PROCESSOR ios"搜索到文章<https://github.com/deeplearning4j/libnd4j/blob/master/cmake/ios-arm.cmake>,其中包含"set(CMAKE_SYSTEM_PROCESSOR armv7)",然后就在本机的iOS.cmake文件中"set(IOS True)"后面加上该行,然后按照之前的步骤重新编译得到的库文件放到iphone中就正常了。后面编译simulator版本的,还是参照pytorch/cpuinfo的issue,不过iOS.cmake中的IOS_ARCH不能添加x86_64,而且也不添加"set(CMAKE_SYSTEM_PROCESSOR armv7)",并且在cmake执行过程中不要加上-DCMAKE_SYSTEM_PROCESSOR=x86_64,然后根据编译ios版本的步骤编译出模拟器版本的库。

        后面编译mac版本时候关键字"cmakelists.txt mac os build"搜索到文章<Mac/linux环境下 如何使用 CMakeLists.txt 编译c++工程>,直接"cmake .. #生成makefile文件"然后"make #编译项目"就可以得到.a文件了。用cmake-gui生成vs2019的工程文件,然后编译得到windows版本的.lib库文件。编译android版本时直接进入到当前目录,执行"ndk-build -j8 NDK_DEBUG=1"即可编译到.a文件,直接ndk-build的时候报"cc1: error: argument to '-O' should be a non-negative integer, 'g', 's' or 'fast'",修改jni\Android.mk文件,将"LOCAL_CFLAGS += -Oz"注释掉即可。

        利用cmake来配置工程的时候报错"No CMAKE_C_COMPILER could be found",看了下对应的CMakeOutput.log和CMakeError.log文件,发现"cmake fatal error LNK1327: 运行 rc.exe",以此作为关键字搜索到文章<Visual Studio报错LINK : fatal error LNK1327: 运行 rc.exe 期间出错>,添加到环境变量中后还是报错,后面参考了文章<LINK : fatal error LNK1158: cannot run 'rc.exe'>,解决了问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值