我试图在c ++中创建一个非常开放的插件框架,在我看来,我已经想出了一个方法,但是一个唠叨的想法一直在告诉我,我正在做的事情非常非常错,它要么不起作用,要么会引起问题.
我对我的框架的设计包括一个调用每个插件init函数的内核.然后,init函数转向并使用内核registerPlugin并registerFunction获取唯一的id,然后分别使用该id注册插件想要访问的每个函数.
函数registerPlugin返回唯一的id.函数registerFunction接受id,函数名和泛型函数指针,如下所示:
bool registerFunction(int plugin_id, string function_name, plugin_function func){}
Run Code Online (Sandbox Code Playgroud)
其中plugin_function是
typedef void (*plugin_function)();
Run Code Online (Sandbox Code Playgroud)
然后内核获取函数指针并将其放在带有function_name和的映射中plugin_id.注册其功能的所有插件必须使函数类型化plugin_function.
为了检索函数,另一个插件调用内核
plugin_function getFunction(string plugin_name, string function_name);
Run Code Online (Sandbox Code Playgroud)
然后该插件必须将其plugin_function转换为其原始类型,以便可以使用它.它通过访问.h文件概述插件提供的所有功能,知道(理论上)正确的类型.插件由by实现为动态库.
这是完成允许不同插件相互连接的任务的聪明方法吗?或者这是一个疯狂而且非常可怕的编程技巧?如果是,请指出我正确的方向来实现这一目标.
编辑:如果需要澄清,请询问并提供.
我们有一个包含多个应用程序的大型项目,因此我们将公共代码移动到单个动态框架中.到目前为止,在64位设备上正常运行,但在32位设备上崩溃如下:
dyld: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment 0 which is not a writable segment (__TEXT) in
/path/to/MyApp.app/Frameworks/MyFramework.framework/MyFramework
Run Code Online (Sandbox Code Playgroud)
一点背景:我们已经编译了很少的其他胖库ARM64,ARMv7然后x86_64架构添加到框架中.我们有一些文本重定位错误,通过添加-read_only_relocs suppress到链接器标志来解决.
如果我们取出ffmpeg和相关的库,它可以在32位设备上正常工作.
有人遇到过这样的错误吗?任何指针或帮助将非常感激.
我正在尝试调试一个将动态库作为插件加载的应用程序,并遇到gdb问题以找到源文件并在源级别放置断点.
我构建了一个动态库(libFoo.so),它使用静态库(libBar.a)编译.
构建libFoo.so后,它将移动到我的主应用程序的plugins目录中,该目录位于不同的文件夹中.
在运行时,应用程序启动并查找此目录,然后加载libFoo.so.所有代码都使用调试信息构建,并为动态库正确加载调试信息.
令我困惑的是,源代码信息没有加载到libFoo的gdb中.这意味着当代码中断了libFoo函数时,我无法看到源代码list或设置断点.
但是,来自libBar的源代码信息(在libFoo.so中静态链接)是完全加载的,当从libBar破解代码并在libBar的代码中放置断点时我可以看到源代码...
更准确地说,这是gdb向我展示共享库的内容:
(gdb) info sharedlibrary Foo
From To Syms Read Shared Object Library
0x... 0x... Yes /path/to/mainapp/plugins/libFoo.so
Run Code Online (Sandbox Code Playgroud)
好的,所以我的lib加载了调试符号.
(gdb) info sources
Source files for which symbols have been read in:
...
/path/to/mainapp/src/main.cpp
/path/to/plugins/libs/bar/bar.cpp
...
Run Code Online (Sandbox Code Playgroud)
所以,gdb已正确加载源代码,libBar.a即使它与可执行文件位于不同的文件夹中,但不是来自与它一起构建的libFoo?
我也尝试在gdb中添加libFoowith 的源目录dir,但无济于事.
我在哪里可以看看帮助gdb建立libFoo与其源码之间的链接?我可以显式指定源文件(而不仅仅是目录dir)吗?还是有一些我缺少的选择?
我从来没有把过多考虑到静态库和动态库之间的大小差异,直到今天我下载了升压的预建库.我发现boost的静态库远远大于动态库.
例如,调试多线程boost wave静态库97.7 mb的大小,而相同的库,但动态,只是1.4 mb大小(包括导入库和DLL)!这是一个巨大的差异.这是为什么?
第二个问题,如果我静态链接,比方说,wave图书馆.这是否意味着我的可执行文件的大小会超过97.7 mb?
boost dynamic-linking static-libraries static-linking dynamic-library
我的C++编译器创建包含动态库的"dylib"文件.什么是.dylib和.so文件之间的区别?
Mach-O格式的文件和ELF格式的文件有什么区别?我必须构建文件供以后在iOS(仅静态库/ Mach-O)和Android(ELF)下使用.
感谢名单!
这是一个理论问题.我知道也许最好的做法是使用共享库.但我遇到了这个问题,似乎无法在任何地方找到答案.
如何构建代码并用ELF格式编译一个C/C++程序,以便可以加载dlopen()?
例如,如果一个可执行文件包含某个函数的实现,int test()并且我想从我的程序中调用此函数(并且最好得到函数的结果),如果可能的话,我该怎么做呢?
在伪代码中,我可以将其描述如下:
ELF可执行文件来源:
void main() {
int i = test();
printf("Returned: %d", i);//Prints "Returned: 5"
}
int test() {
return 5;
}
Run Code Online (Sandbox Code Playgroud)
外部计划:
// ... Somehow load executable from above
void main() {
int i = test();
printf("Returned: %d", i);//Must print "Returned: 5"
}
Run Code Online (Sandbox Code Playgroud) 假设我在静态库中有一个单例类S,这可以与其他动态库D1 D2 D3链接,
所以根据我的理解,类S将在每个D1,D2和D3中有一个单独的实例,即使它不是单例(如全局)也是如此
有没有办法防止S类的多个副本?我不能将单例S放在另一个动态库中.
Executable
/ | \ \
D1 D2 D3 D4
| | |
S S S
Run Code Online (Sandbox Code Playgroud)
编辑:单例S在一个单独的静态库中,分别与D1 D2 D3 ...链接.
单例在堆中分配,只有指针是静态的
static s::instance()
{
static smart_ptr<S> ptr = NULL;
if(ptr == NULL) ptr = new S;
return ptr;
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:
我做了一个简单的测试用例来检查出来这是一个示例makefile(用.so替换.d)我做了检查,我在Ubuntu和Cygwin上检查过,两个g ++编译器和行为都不同.cygwin创建了2个不同的对象但是ubuntu创建了1个对象
all: dynamic1 dynamic2 main
static: static.cpp
g++ -c -fPIC static.cpp -o obj/static.o
ar rvs lib/static.a obj/static.o
dynamic1: static dynamic1.cpp
g++ -fPIC -shared dynamic1.cpp lib/static.a -o lib/libdynamic1.dll
dynamic2: static dynamic2.cpp
g++ -fPIC -shared dynamic2.cpp lib/static.a …Run Code Online (Sandbox Code Playgroud) c++ singleton design-patterns static-libraries dynamic-library
我在将 macOS 应用程序与 C 库链接时遇到一些问题。我有几个与这个问题相关的问题。
考虑到这将是非常自定义的库而不是与其他应用程序共享,最好将应用程序链接到动态或静态库?
我已将我的 macOS Xcode 应用程序与 ~14 个静态库 .a 链接起来,并且工作正常。我已经重新配置了 CMakeLists.txt 来创建这个库,但现在 Xcode 项目无法工作。主要的变化是改变我的目录
"$(SRCROOT)/../../c/<project_name>/outputs/lib/apple/static"
但现在我在同一路径中同时拥有静态(.a)和动态(.dylib)库
"$(SRCROOT)/../../c/server/outputs/lib/apple"
我不知道这是否重要,但是链接到静态库会导致运行我的 Xcode 项目后它抱怨无法加载lib.dylib所以也许它在库搜索路径下找到了这个动态库并且厌倦了加载它们但不'没有发现它们有联系吗?
也许我应该在这里改变一些东西?但是,如果我将我的应用程序分发到其他一些在此特定位置没有库的计算机,该怎么办?如何在 Xcode 包中包含动态库以便始终可以找到。
我知道我可能添加了很多问题。但想知道如何最好地解决这个问题?最好静态或动态链接,然后如何正确实现此目的以避免此错误。
更新
.dylib只有当我将此库目录的路径添加到Runpath Search Paths..a它在.dylib不在同一目录中时可以工作(我将.a库移动到/static子目录中),然后对于这个移动的库错误不再显示。但是,当同一目录中有.a和.dylib库时,是否有办法静态链接?我一直在尝试提交一个带有 Obj-C 动态库 (.dylib) 的 Swift 应用程序,但它不断被 iOS 应用商店拒绝,并显示错误消息,例如
\n\n\n\n\n无效 Swift 支持 - 文件 libswiftDarwin.dylib、\n libswiftDispatch.dylib、libswiftCoreGraphics.dylib、\n libswiftUIKit.dylib、libswiftCore.dylib、libswiftFoundation.dylib、\n libswiftQuartzCore.dylib、libswiftObjectiveC.dylib、\n libswiftCoreImage.dylib 为\xe2\x80\x99t 位于预期位置\n /Payload//Frameworks。将文件移动到预期位置,使用当前公共 (GM) 版本的 Xcode 重新构建应用程序,然后重新提交
\n
来自Apple文档https://developer.apple.com/library/archive/technotes/tn2435/_index.html#//apple_ref/doc/uid/DTS40017543-CH1-PROJ_CONFIG-APPS_WITH_DEPENDENCIES_BETWEEN_FRAMEWORKS错误“可能表明您的应用程序是嵌入未打包为框架的动态库。框架包外部的动态库(通常具有文件扩展名 .dylib)在 iOS、watchOS 或 tvOS 上不受支持,除了 Xcode 提供的系统 Swift 库之外。 ”
\n\n因此,下一步是将动态库(作为子项目)嵌入到 Cocoa Touch Framework 项目中。设置完成后,尽管框架构建得很好,但我还是陷入了导入 dylib 类的“符号未找到”错误。
\n\n我想知道实现这个项目结构所需的步骤,或者它是否可以在 iOS 上实现。
\n我尝试将一个非常简单的动态库项目编译为.dll文件.项目名称为"Library".我正在使用Visual Studio 2015,项目属性如下:
在项目中只有两个文件:ClassA.h和ClassA.cpp.
ClassA.h中的代码是:
#ifndef CLASSA_H
#define CLASSA_H
using namespace std;
#ifdef LIBRARY_EXPORTS
#define CLASSA_API __declspec(dllexport)
#else
#define CLASSA_API __declspec(dllimport)
#endif
class ClassA
{
public:
static CLASSA_API void func();
};
#endif
Run Code Online (Sandbox Code Playgroud)
ClassA.cpp中的代码是:
#include "ClassA.h"
#include <iostream>
void ClassA::func()
{
cout << "SUCCESS!" << endl;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此项目时,我收到此错误:
严重性代码说明项目文件行错误必须定义LNK1561入口点库C:\ Users\UX303\Documents\Visual Studio 2015\DLLTest\Library\LINK 1