我们可以使用GHC API或其他东西加载非文本源模块,但AST表达式,类似于haskell-src-exts Exp类型?这样我们就可以节省代码生成和解析的时间.
我使用 OS X 10.7 (Lion)、XCode 4.6.3 和 libstdc++ 作为 C++ 标准库。
我的主项目中有这段代码:
共享.cpp:
extern "C" int sharedFun()
{
return 5;
}
Run Code Online (Sandbox Code Playgroud)
在我的副项目中,需要动态加载主项目:
加载器.cpp:
#include <dlfcn.h>
int main(int argc, const char * argv[])
{
void* mainApp = dlopen("mainApp.dylib", RTLD_LAZY);
char* error;
dlsym(mainApp, "sharedFun");
if ((error = dlerror()) != nullptr)
{
....
}
}
Run Code Online (Sandbox Code Playgroud)
纳米输出:
nm -gU mainApp.dylib | grep sharedFun
002a3a10 - 01 0000 FUN _sharedFun
002a3a10 T _sharedFun
Run Code Online (Sandbox Code Playgroud)
dlopen 加载库很好,但 dlsym 返回“符号未找到”。有任何想法吗?
谢谢。
我想通常使用libdl动态加载C ++。问题是在运行时识别已被名称篡改的符号。
如此处所述,一种解决方案是通过使用extern“ C”删除名称修饰。
http://www.tldp.org/HOWTO/C++-dlopen/theproblem.html
该解决方案具有将动态加载的资源限制为C样式接口的缺点。例如,动态加载的函数不能是重载函数。
什么是克服此限制的好方法?
一种可能的解决方案是使用链接函数命名库源代码的工具,以在需要链接库时获取修改后的名称。llvm是否为此提供工具?
可能一个笨拙的解决方案是使用函数签名的函数,使用具有签名的函数创建伪代码,将其与用于生成程序集的标志一起使用的编译器传递到编译器,解析输出以获取错误的名称并返回整齐的名称作为字符串。然后可以将字符串传递给dlsym()。
为了使问题更具体,这里有两个示例程序,它们说明了外部“ C”解决方案在不修改库代码的情况下无法动态加载的内容。第一个以传统的C ++方式动态链接库。第二个使用dlopen。在第一个程序中链接重载函数很简单。在第二个程序中没有简单的方法链接重载函数。
程序1:加载时动态链接
main.cpp
// forward declarations of functions that will be linked
void say(int);
void say(float);
int main() {
int myint = 3;
say(myint);
float myfloat = 5.0f;
say(myfloat);
}
Run Code Online (Sandbox Code Playgroud)
说
#include <iostream>
//extern "C" function signatures would collide
//extern "C" void say(int a) {
void say(int a) {
std::cout << "The int value is " << a << ".\n";
}
//extern "C" void say(float a) {
void say(float …Run Code Online (Sandbox Code Playgroud) 今天我正在寻找一些关于动态加载器内部深层魔法的启示。我正在对 Linux 上运行的 C++ 应用程序的插件系统进行调试/故障排除。它通过dlopen(RTLD_NOW | RTLS_LOCAL) 加载插件并使用dlclose. 人们可能会想,没什么特别的。
但是,我注意到即使在dlclose成功调用*之后,某些插件仍保持加载状态。我在使用pmap查看正在运行的进程的内存映射后得出了这一结论。一些库会立即从进程内存中删除,而另一些库显然会无限期地徘徊。
继续,dlopen 手册页指出:
函数 dlclose() 减少动态库句柄句柄上的引用计数。如果引用计数降至零并且没有其他加载的库使用其中的符号,则卸载动态库。
这意味着问题归结为这两种可能性;要么引用计数不为零,要么其他加载的库正在使用某些(但不是全部)插件中的符号。
我非常确定(尽管不是 100%)引用计数为零。应用程序的插件管理器以完全相同的方式处理所有插件。它还确保插件不会被多次加载。因此,IMO 加载和卸载对于所有插件来说应该表现相同。
这就留下了第二种可能性:其他加载的库正在使用插件中的符号。另一个“不应该发生这种事”的典型案例。虽然这当然是可能的。我们正在使用 gcc 和默认可见性,据我所知,没有任何内容被删除,因此正在导出大量符号。实际上这让我更担心,因为这些插件应该是独立的。
以下是我目前的未决问题:
dlopen您知道验证引用计数的方法吗?我的机器是: Linux 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:44 UTC 2014 i686 i686 i686 GNU/Linux
*我应该提到的是,所有的加载和卸载都发生在主线程中,所以这里应该不存在多线程问题。
当您dlopen()是共享对象时,是否有一种机制可以让该 DLL 中的代码在不被显式调用的情况下执行?具体来说,调用者dlopen()可能不知道的全局变量/静态变量的 C++ 静态初始化代码?我很确定答案应该是“是”,但我不记得是什么机制导致这种情况发生,以及如何利用它来运行任意代码。
c++ shared-objects dynamic-loading dlopen static-initialization
我有一堆从导入的类创建的对象
module = imp.load_source(packageName, packagePath)
Run Code Online (Sandbox Code Playgroud)
我要泡菜 只要packagePath直接在Python路径或工作目录中,一切都可以完美工作。
但是一旦我将其移动到其他地方,我就会感到恐惧
ImportError: No module named test_package
Run Code Online (Sandbox Code Playgroud)
我尝试添加一种__reduce__将类作为第一个值返回的方法。我尝试使用dill,它应该能够序列化完整的类,而不是对该类的简单引用(并且我尝试将其与结合使用__reduce__)。
当前的工作方式是,将它们与包路径一起双击在一个负责导入包的对象中:
class Container(object):
def __init__(self, packagePath, packageName, objectsDump= None):
self.package = imp.load_source(packageName, packagePath)
self.packagePath = packagePath
self.packageName= packageName
if objectsDump is not None:
self.objects = dill.loads(objectsDump)
def __reduce__(self):
return (self.__class__,
(self.packagePath, self.packageName, dill.dumps(self.objects))
Run Code Online (Sandbox Code Playgroud)
我发现这种方式确实令人费解,我想知道:是否有更Python化的方式来实现这一目标?
注意:所有这些都发生在Python 2.7.10,莳萝0.2.6中。所有要序列化的对象都是新型对象(继承自object)。
我已经BaseClass在 NodeJS Typescript 项目中定义了一个抽象,并且我有一个实现和扩展它的派生类列表BaseClass。
// baseModule.ts
export abstract class BaseClass {
constructor() {}
abstract method(): void;
}
export interface ModuleConstructor<T extends BaseClass> {
new (): T
}
export function createModule<T extends BaseClass>(type: ModuleConstructor<T>): T {
return new type();
}
Run Code Online (Sandbox Code Playgroud)
我试图找到一种在运行时以编程方式创建这些类之一的实例的方法。
这里的限制是我希望能够将一个新myDerivedClass.ts文件放入我的项目文件夹中,并在运行时自动将其包含在可用模块列表中。
开发人员的工作流程是 1) 创建新文件myNewModule.ts2) 创建并导出一个扩展类BaseClass3) 保存myNewModule.ts到./myModules
// ./myModules/myNewModule.ts
export class MyModule extends BaseClass {
constructor() {
super()
}
method() {
//Do something custom
}
}
Run Code Online (Sandbox Code Playgroud)
运行时流程(理想情况下无需重建)将是 1) …
I have a spring boot application which has two functionalities Http requests and kafka Messages handling. I want this application to run in mode which is enabled from application.yml i.e if the user wants to enable it only for http requests then kafka should not be connected.
I could achieve this using normal spring boot kafka plugin by disabling auto configure using the following property at @KafkaListener,
autoStartup="${module.put:false}"
现在我们正在尝试转向云流,我发现通过删除云流和活页夹库来禁用它的唯一方法。有没有更好的方法使用自动配置模式的属性来禁用它,或者是否有任何手动配置选项可用?
dynamic-loading apache-kafka spring-cloud-stream spring-cloud-stream-binder-kafka
我想了解动态加载程序如何为 ELF 段创建映射的详细信息。
考虑一个与 GNU ld 链接的小型共享库。程序头是:
类型偏移 VirtAddr PhysAddr FileSiz MemSiz Flg Align 加载 0x000000 0x0000000000000000 0x0000000000000000 0x00095c 0x00095c RE 0x200000 负载 0x000df8 0x0000000000200df8 0x0000000000200df8 0x000250 0x000258 RW 0x200000 动态 0x000e08 0x0000000000200e08 0x0000000000200e08 0x0001d0 0x0001d0 RW 0x8 GNU_EH_FRAME 0x000890 0x0000000000000890 0x0000000000000890 0x00002c 0x00002c R 0x4 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 GNU_RELRO 0x000df8 0x0000000000200df8 0x0000000000200df8 0x000208 0x000208 R 0x1
这个共享对象可以打印它在 ( /proc/self/maps) 中加载的进程的映射,片段:
7fd1f057b000-7fd1f057c000 r-xp 00000000 fe:00 12090538 /path/libmy.so 7fd1f057c000-7fd1f077b000 ---p 00001000 fe:00 12090538 /path/libmy.so 7fd1f077b000-7fd1f077c000 …
dynamic-loading ×10
c++ ×3
dlopen ×2
linux ×2
apache-kafka ×1
c ×1
dill ×1
dlsym ×1
elf ×1
es6-modules ×1
ghc-api ×1
glibc ×1
haskell ×1
libraries ×1
macos ×1
node.js ×1
python ×1
python-2.7 ×1
spring-cloud-stream-binder-kafka ×1
typescript ×1
xcode ×1