我想使用LoadLibrary开发一个插件系统.
我的问题是:我希望我的功能需要一个const char*并且LoadLibrary需要一个LPCTSTR.
我有一个聪明的主意(LPCSTR)path,不断给我一个模块未找到错误.
目前的代码如下.如果我取消注释该widepath = L..行,它可以正常工作.我已经阅读了使用MFC的解决方案,但我不想使用MFC.
当前代码:
bool PluginLoader::Load(char *path)
{
path = "Release\\ExamplePlugin.dll";
LPCTSTR widepath = (LPCTSTR)path;
//widepath = L"Release\\ExamplePlugin.dll";
HMODULE handle = LoadLibrary(widepath);
if (handle == 0)
{
printf("Path: %s\n",widepath );
printf("Error code: %d\n", GetLastError());
return false;
}
int (*load_callback)() = (int (*)()) GetProcAddress(handle, "_plugin_start@0");
if (load_callback == 0)
{
return false;
}
return load_callback() == LOAD_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud) 是否有一个独立于平台的Java语句来从与Java源代码不同的目录中加载本机库?我想用这样的东西:
public class HelloWorld {
static {
System.loadLibrary("../some_project/HelloWorld");
}
public static native void print();
}
Run Code Online (Sandbox Code Playgroud)
问题是System.loadLibrary()不支持pathname参数中的目录分隔符.另外,不幸的是,System.load()需要一个绝对路径名,这不仅意味着我不能像上面那样指定一个相对目录(我想做),但它还要求参数包括,例如,前面的Linux系统上JNI库名称的"lib"和".so"扩展名.
有没有一种标准的处理方式?如果可能的话,我想避免编写一堆依赖于平台的Java代码来构造正确的JNI库名.
我正在写一个JNI程序,我想在我使用它之后卸载dll.我能为此目的做些什么?我unloadLibrary()在Javadoc中找不到方法.
我正在使用多个DLL的Windows应用程序(EXE).开发在VCExpress 2005(VC 8.0)中,仅使用C语言.
其中一些DLL是插件/加载项/扩展,它们LoadLibrary根据EXE读取的配置文件动态加载.
重要的是:应用程序必须是可移植的(能够在没有安装的情况下从USB闪存驱动器或类似驱动器运行),并且插件DLL可能与应用程序EXE不在同一文件夹中(遗留原因).
使用MSVC6,这很简单:编译,链接,分发EXE和DLL.
使用MSVC8,C运行时库(MSVCRT)不再随操作系统一起分发,因此无法依赖它安装.为了满足可移植性要求,我需要使用私有程序集.所有EXE和DLL都已嵌入其清单.
我的问题:通过加载的插件DLL LoadLibrary()找不到EXE文件夹中的私有程序集,因此尝试加载它们会失败,除非Microsoft.VC80.CRT程序集安装在winSxS中.
问题:如果清单从插件DLL中删除,一切正常.
我的问题:
在问题的情况下,Windows似乎不遵循程序集搜索序列或动态链接库搜索顺序.具体来说,它是在加载DLL的路径中查找私有程序集,而不是从中加载应用程序(EXE).
我试图通过将程序集放在DLL附近,并更改当前目录(以排除与工作目录案例相关)来验证这一点,并获得预期的行为.任何人都可以确认这是LoadLibrary与SxS一起使用时的正常行为吗?
我是否正确地假设没有清单,DLL会回退到非SxS加载顺序,它在EXE的文件夹中找到msvcr80.dll(而不是程序集清单Microsoft.VC80.CRT.manifest)?
如果我对(1)和(2)是正确的,那么只要从DLL中排除清单我会失去什么?改写,为什么我不应该通过排除清单来解决我的问题?
如果我有两个对编译的C代码进行本机调用的Java类并且我在另一个类中调用这两个类,它会影响内存吗?例如,我有A类和B类,同时调用本机函数.它们的设置如下:
public class A{
// declare the native code function - must match ndkfoo.c
static {
System.loadLibrary("ndkfoo");
}
private static native double mathMethod();
public A() {}
public double getMath() {
double dResult = 0;
dResult = mathMethod();
return dResult;
}
}
public class B{
// declare the native code function - must match ndkfoo.c
static {
System.loadLibrary("ndkfoo");
}
private static native double nonMathMethod();
public B() {}
public double getNonMath() {
double dResult = 0;
dResult = nonMathMethod();
return dResult;
} …Run Code Online (Sandbox Code Playgroud) 我想加载相同的DLL,例如Lib.dll多次!
- >需要为每个LoadLibrary创建一个新进程(CreateProcess函数)!
任何人都有一个例子或一些提示?!
谢谢和问候
我正在研究一个动态加载DLL作为插件的程序.我正在使用Microsoft Visual C++ 2008编译程序.但是,我们假设应该支持任何与Qt一起工作的Visual C++版本.程序目录布局如下:
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| program.exe
Run Code Online (Sandbox Code Playgroud)
program.exe发现所有插件DLL文件,对它们执行LoadLibrary()并调用某个签名函数来查明它是否实际上是一个插件.这对于安装了MSVC90的vcredist的计算机非常有效.当然,要使程序在所有计算机上运行,我必须使用msvc*.dll文件和相应的清单文件重新分发它.Qt DLL还需要redist才能运行.
现在,我已经设置了cmake来根据所选的Visual Studio版本自动复制适当的redist DLL和manifest.为了简单起见,让我们继续假设我正在使用MSVC90.当redist被复制到程序目录时,布局如下所示:
| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| msvcm90.dll
| msvcp90.dll
| msvcr90.dll
| Microsoft.VC90.CRT.manifest (I'm also aware that this file is bugged in VS2008)
| program.exe
Run Code Online (Sandbox Code Playgroud)
关于清单文件中的错误:http://www.cmake.org/pipermail/cmake/2008-Stembertember/023822.html
具有此布局的程序现在可以在没有安装redist的计算机上运行,但插件没有加载.为了让插件加载,我必须执行以下操作之一:
plugins/目录.从清单文件中删除对msvc*.dll文件的所有引用.这有效,但它并不好,因为我必须支持不同版本的已编辑清单文件,具体取决于使用的MSVC的版本.此外,我不知道这是否会在2008年以外的Visual Studio中破坏.plugins/目录.这不需要对清单文件进行任何修改,但现在program.exe愚蠢地尝试加载msvc*.dll文件,认为它们是插件.当然,这会优雅地失败,所以不会造成太大的伤害.另一个缺点是程序包的大小增加了1 MB以上.不过,这两个问题都是我可以接受的.program.exe/ MD 都不会破坏任何东西.什么是最好的解决方案?什么是正确的解决方案?如果有多个正确的解决方案,那么这是最佳做法?我是第一个尝试这样做的人吗? …
我有用C编写的本机源代码,我想在我的Android设备(Nexus 7)上运行.我已经成功地使用Android NDK在Android上运行本机代码进行了大量研究和在线教程.我对此有了一些了解.但是,我所使用的代码利用了complex.h中定义的标准数学库的复杂功能.然而,NDK C库似乎不支持复杂的功能.每当我对项目进行ndk-build时,我得到:
fatal error: complex.h: no such file or directory.
Run Code Online (Sandbox Code Playgroud)
作为一个解决方案,我想从arm-linux-gnueabi获取标准数学库(libm.a)并将其与我的本地源链接.这是我的Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := StandardC
LOCAL_SRC_FILES := libc.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := mathLib
LOCAL_SRC_FILES := libm.a
LOCAL_STATIC_LIBRARIES := StandardC
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ComplexOperations
LOCAL_SRC_FILES := libComplexOperations.a
LOCAL_STATIC_LIBRARIES := mathLib
LOCAL_C_INCLUDES += /usr/arm-linux-gnueabi/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MySource
LOCAL_CFLAGS += -std=c99
LOCAL_SRC_FILES := com_samuel_test_ComplexOperationsLib.c
LOCAL_C_INCLUDES += /usr/arm-linux-gnueabi/include
LOCAL_STATIC_LIBRARIES := ComplexOperations
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)
我不得不链接arm-linux-gnueabi-gcc的libc以及libm需要它.使用arm-linux-gnueabi-gcc和编译器标志-march = armv7-a静态编译"ComplexOperations"模块.该库使用complex.h.这种构建没有任何错误和警告.但是当我运行应用程序并打电话时
System.loadLibrary("MySource");
Run Code Online (Sandbox Code Playgroud)
我在logcat上遇到这个错误: …
我有java程序Client.class,它通过JNI使用cpp共享库libclient.so.libclient.so构建为共享并使用cpp共享库libhttp.so.
libclient.so和libhttp.so放在/home/client/lib64
Client.class 文件夹中/home/client/bin
客户端可以加载库
第一种方式很好.
export LD_LIBRARY_PATH = /home/client/lib64
java -classpath ./bin客户端
secon方式失败了.
java -classpath ./bin -Djava.library.path=./../lib64 Client
java.lang.UnsatisfiedLinkError: /home/client/lib64/libclient.so: libhttp.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)
当我将libhttp.so放入/ usr/lib64时,第二种方式正常.
如果我使用System.loadLibrary,为什么libclient.so在/ usr/lib64中寻找libhttp.so?如何在不将libhttp.so复制到/ usr/lib64的情况下修复它?
我的加载代码:
//Try load from -Djava.library.path
boolean found = false;
String lib = "client";
try {
System.loadLibrary(lib);
found = true;
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}
//Try load from LD_LIBRARY_PATH
if (!found) {
lib = "libclient.so";
String ld_lib_path = …Run Code Online (Sandbox Code Playgroud) java java-native-interface loadlibrary java.library.path unsatisfiedlinkerror
我的proj1.dll它依赖于另一个 DLL proj2.dll,. 我是proj1.dll针对VS2013中编译时编译器输出的导入库进行编译的proj2.dll。我还导出了我有兴趣使用的公共函数。所以现在我有两个独立的 DLL,它们都符合“cdll”标准。
我想在 Python 中使用proj1.dll,但遇到以下问题:
import ctypes
# Crashes saying no entry point for "some_func" in proj2.dll
ctypes.cdll.LoadLibrary("C:\myfolder\proj1.dll")
ctypes.cdll.LoadLibrary("C:\myfolder\proj2.dll") # Loads fine
ctypes.cdll.LoadLibrary("C:\myfolder\proj1.dll") # Loads fine if proj2 is loaded first
Run Code Online (Sandbox Code Playgroud)
以前,当我构建proj2为静态库并在proj1. 这两个 DLL 存在于同一文件夹中。我什至尝试将文件夹的路径添加到我的 PATH 环境变量中,以查看这是否是路径问题,但没有任何改变。
我假设 Windows 将加载proj1.dll然后加载 dll 的依赖项。我错了吗?调用者(Python)是否必须首先加载依赖DLL?有谁知道为什么会发生这种情况?