我正在考虑选择Adobe AIR作为即将推出的项目的客户端实现技术.(之前的选择是C#和WPF,但最近我对Flash/Flex/AIR印象非常深刻.)
但是我的产品最重要的功能之一将是它的插件架构,允许第三方开发人员以有趣的方式扩展功能和GUI.
我知道如何在C#中设计架构:插件加载器将枚举本地"app/plugins /"目录中的所有程序集.对于每个程序集,它会枚举所有类,寻找"IPluginFactory"接口的实现.对于工厂创建的每个插件,我会询问它的MVC类,并将其GUI元素(菜单项,面板等)捕捉到现有GUI布局中的相应插槽中.
我想在AIR中完成同样的事情(从本地文件系统加载插件,而不是从Web加载).阅读本文之后,我的理解是,它是可能的,并且基本架构(将SWF加载到沙盒ApplicationDomains等中)与您在.NET中的方式非常相似.
但我对这些陷阱感到好奇.
如果您有任何人使用Flash播放器进行任何动态类加载(最好是在混合flash/flex应用程序中,特别是在AIR主机中),我很想知道您构建插件框架的经验以及遇到棘手情况的地方使用Flash播放器,以及flash,flex和AIR API.
例如,如果有人问我同样的问题,但考虑到Java平台,我肯定会提到JVM没有"模块"或"程序集"的概念.最高级别的聚合是"类",因此在插件系统中创建用于管理大型项目的组织结构可能很困难.我还将讨论多个类加载器的问题,以及每个类加载器如何维护自己独立的加载类实例(具有自己独立的静态变量).
以下是一些仍未解决的具体问题:
1)actionscript"Loader"类可以将SWF加载到ApplicationDomain中.但该appdomain究竟包含什么?模块?类?MXML组件是如何表示的?如何找到实现我的插件界面的所有类?
2)如果您已将插件从主应用程序加载到单独的ApplicationDomain中,从其他应用程序域调用代码是否更加复杂?关于可以通过app -main域间编组层的数据类型是否有任何重要的限制?编组是否过于昂贵?
3)理想情况下,我想将自己的大部分主代码作为插件开发(主应用程序只是一个插件加载shell)并使用插件架构将该功能提升到应用程序中.这会让你内心感到害怕吗?
我的问题:
这是一个例子.上面的问题归结为C是否保证main.c打印: "Function equality: 1"或者"Function equality: 0",在第一种情况下,动态加载器如何实现这一点.
common.h:
extern void * getc_main;
extern void * getc_shared;
void assign_getc_shared();
Run Code Online (Sandbox Code Playgroud)
main.c:
#include <stdio.h>
#include "common.h"
int main()
{
getc_main = (void*) getc;
assign_getc_shared();
printf("Function equality: %d\n", getc_main == getc_shared);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
shared.c:
#include <stdio.h>
#include "common.h"
void assign_getc_shared()
{
getc_shared = (void*) getc;
}
Run Code Online (Sandbox Code Playgroud)
在Unix中,这将使用以下命令进行编译:
cc -shared -fPIC -o libshared.so shared.c
cc -o main main.c -L. -lshared
Run Code Online (Sandbox Code Playgroud)
并执行:
LD_LIBRARY_PATH=. ./main
Run Code Online (Sandbox Code Playgroud) 这里是一个真正的JQuery UI天才:我们有一个非常长的形式,按需加载部分(例如,当点击索引/导航时,或当我们在当前部分的边缘滚动时).
当我在当前查看的部分下面加载部分时,这不会影响当前滚动(即scrollTop)位置,但是当我在当前查看部分上方插入新部分时,它当然会将查看的内容推下来.
我们需要保持相对于当前部分的scrollTop位置.我们还需要在进行调整时避免显示跳跃/毛刺.
我想要任何实际上必须解决这个问题的人提出一些建议.重要的是屏幕不会出现故障,因此应避免将scrollTop同步到缓慢的DOM更新.
对拟议解决方案的建议或意见?是否有可以执行此操作的滚动替换?
如果你无法解决它,但认为它值得解决,请考虑提升,这样我就可以获得大笔奖金!:)
模块加载如何在CPython下工作?特别是,用C编写的扩展的动态加载如何工作?我在哪里可以了解到这一点?
我发现源代码本身相当压倒性.我可以看到,可靠的ol' dlopen()和朋友用在支持它的系统上但没有任何大局观,从源代码中解决这个问题需要很长时间.
关于这个主题可以写很多,但据我所知,几乎没有任何内容 - 描述Python语言本身的大量网页使搜索变得困难.一个很好的答案将提供一个相当简短的概述和参考资源,我可以了解更多.
我最关心的是它是如何在类Unix系统上运行的,因为这就是我所知道的但我感兴趣的是如果这个过程在其他地方类似.
为了更具体(但风险假设太多),CPython如何使用模块方法表和初始化函数来"理解"动态加载的C?
python cpython dynamic-loading python-import python-internals
我编写了一小段关于动态加载程序集和从这些程序集创建类实例的代码,包括可执行文件,要动态加载的测试库和用于将动态程序集加载到新程序集的加载程序库Appdomain.Loader库由可执行文件和动态库引用.
//executable
[System.STAThreadAttribute()]
[System.LoaderOptimization(LoaderOptimization.MultiDomain)]
static void Main(string[] args)
{
AppDomainSetup domainSetup = new AppDomainSetup()
{
ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
LoaderOptimization = LoaderOptimization.MultiDomain
};
AppDomain childDomain = AppDomain.CreateDomain("MyDomain", null, domainSetup);
Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.LoaderOptimization.ToString());
Console.WriteLine(childDomain.SetupInformation.LoaderOptimization.ToString());
byte[] assembly = null;
string assemblyName = "CSTestLib";
using (FileStream fs = new FileStream(assemblyName+".dll",FileMode.Open))
{
byte[] byt = new byte[fs.Length];
fs.Read(byt,0,(int)fs.Length);
assembly = byt;
}
object[] pararmeters = {assemblyName,assembly};
string LoaderAssemblyName = typeof(AssemblyLoader).Assembly.FullName;
string LoaderClassName = typeof(AssemblyLoader).FullName;
AssemblyLoader assloader = (AssemblyLoader)childDomain.CreateInstanceAndUnwrap(LoaderAssemblyName,LoaderClassName , …Run Code Online (Sandbox Code Playgroud) 假设这两种方法都正确加载脚本,并且在使用脚本之前等待适当的时间(和/或使用回调),这些方法之间的主要区别是什么.
注意:我理解第一个使用jQuery(这是一个更大的下载等).我真正感兴趣的是这些方法的影响.是否将脚本放在与另一个不同的范围内?等等.
jQuery的:
function loadScript() {
$.getScript('http://www.mydomain/myscript.js');
}
Run Code Online (Sandbox Code Playgroud)
附加到身体:
function loadScript() {
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'http://www.mydomain/myscript.js';
script.async = true;
document.body.appendChild(script);
}
Run Code Online (Sandbox Code Playgroud)
追加头:
function loadScript() {
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= 'http://www.mydomain/myscript.js';
script.async = true;
head.appendChild(script);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试动态加载和执行模块,
以下是我的代码
TestModule.hs
module TestModule
where
evaluate = "Hello !!!"
Run Code Online (Sandbox Code Playgroud)
Invoke.hs
module Invoke
where
import GHC
import DynFlags
import GHC.Paths (libdir)
import Unsafe.Coerce (unsafeCoerce)
import Data.Dynamic
execFnGhc :: String -> String -> Ghc a
execFnGhc modname fn = do
mod <- findModule (mkModuleName modname) Nothing
--setContext [IIModule mod]
GHC.setContext [ GHC.IIDecl $ (GHC.simpleImportDecl . GHC.mkModuleName $ modname) {GHC.ideclQualified = True} ]
value <- compileExpr (modname ++ "." ++ fn)
let value' = (unsafeCoerce value) :: a
return value'
Run Code Online (Sandbox Code Playgroud)
Main2.hs
import …Run Code Online (Sandbox Code Playgroud) 我用了
readelf --dyn-sym my_elf_binary | grep FUNC | grep UND
Run Code Online (Sandbox Code Playgroud)
my_elf_binary从动态符号表中.dynsym精确显示动态符号表中的动态导入函数.示例输出将是:
[...]
3: 00000000 0 FUNC GLOBAL DEFAULT UND tcsetattr@GLIBC_2.0 (3)
4: 00000000 0 FUNC GLOBAL DEFAULT UND fileno@GLIBC_2.0 (3)
5: 00000000 0 FUNC GLOBAL DEFAULT UND isatty@GLIBC_2.0 (3)
6: 00000000 0 FUNC GLOBAL DEFAULT UND access@GLIBC_2.0 (3)
7: 00000000 0 FUNC GLOBAL DEFAULT UND open64@GLIBC_2.2 (4)
[...]
Run Code Online (Sandbox Code Playgroud)
假设与这些符号相关联的名称(例如tcsetattr或access)始终是唯一的,是否安全?或者是否有可能或合理的*),有一个动态符号表(过滤为FUNC和UND),其中包含两个具有相同关联字符串的条目?
我问的原因是我正在寻找动态导入函数的唯一标识符...
*)动态链接器不会将UND FUNC具有相同名称的所有" 符号" 解析为相同的函数吗?
大多数在Linux上使用OpenGL的应用程序(和库)libGL.so在运行时使用dlopenAPI 加载,而不是动态链接它.
他们为什么这样做呢?
我能想象的唯一原因是因为任何图形驱动程序供应商都提供了不同的libGL,而且两种不同的libGL可能是ABI不兼容的.(嗯,哼,他们为什么要ABI不兼容?即使它们是,为什么加载它们dlopen会解决这个问题?)
无论如何,假设有这么好的理由,我也想这样做.有没有人有一个开源C/C++代码的链接,通过加载所有OpenGL函数dlopen,我可以包含到我的项目,而不需要太多的调整?
我浏览了下面的链接,通过它我了解了如何创建和使用共享库。 https://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html
Step 1: Compiling with Position Independent Code
$ gcc -c -Wall -Werror -fpic foo.c
Step 2: Creating a shared library from an object file
$ gcc -shared -o libfoo.so foo.o
Step 3: Linking with a shared library
$ gcc -L/home/username/foo -Wall -o test main.c -lfoo
Step 4: Making the library available at runtime
$ export LD_LIBRARY_PATH=/home/username/foo:$LD_LIBRARY_PATH
$ ./test
This is a shared library test...
Hello, I am a shared library
Run Code Online (Sandbox Code Playgroud)
但是,我有几个问题: