我正在尝试用.NET组装一个插件系统,我不确定我是否正确地进行了操作.该系统的基础是一个特定的目录({apppath}/Plugins /)将有一堆预编译的DLL,我想通过反射来查看每个目录,并且对于每个可用的类,如果它继承了特定的基类(这是在另一个DLL中定义的,但我将在稍后介绍),然后创建它的实例并在所述实例中调用特定的函数.
Public Sub ScanPluginsInDirectory(ByVal Directory As String)
Dim Plugins As New IO.DirectoryInfo(Directory)
Dim Files As IO.FileInfo() = Plugins.GetFiles("*.dll")
Dim CryptType As Type = GetType(CryptPluginBase)
Dim PluginsData as List(Of LoadedPluginsInfo)
For Each DllFile As IO.FileInfo In Files
Try
Dim thisAsm As Assembly = Assembly.LoadFrom(DllFile.FullName)
Dim ClassDefs = thisAsm.GetTypes().Where(Function(type) CryptType.IsAssignableFrom(type))
For Each ClassDef As Type In ClassDefs
Dim A As Object
A = ClassDef.Assembly.CreateInstance(ClassDef.Name)
PluginsData.Add(New LoadedPluginsInfo(A.Plugin(), False))
Next
Catch ex As Exception
Continue For
End Try
Next
End Sub
Run Code Online (Sandbox Code Playgroud)
我遇到的具体问题是,我不确定这是否是正确的方法.如果可以假设A.Plugin() …
如何用c语言实现后期绑定?任何人都可以提供一个例子.
我认为可以使用dlopen和dlsym来实现,但我不确定它.如果我错了,请纠正我!
使用与对象/属性名称生成相关的WebBrowser后期绑定调用存在问题.
例如:
WebBrowser1.Document.DomDocument.Forms.Myform.mycontrol.Value = "test"
Run Code Online (Sandbox Code Playgroud)
将使用多个WebBrowser控件实例失败
实际发生的是mycontrol对象变为Mycontrol并且编译后的vb.net应用程序将失败并出现错误
找不到会员.(来自HRESULT的异常:0x80020003(DISP_E_MEMBERNOTFOUND))Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o,Type objType,String name,Object [] args,String [] paramnames,Boolean [] CopyBack)at Microsoft.VisualBasic. CompilerServices.NewLateBinding.LateGet(Object Instance,Type Type,String MemberName,Object [] Arguments,String [] ArgumentNames,Type [] TypeArguments,Boolean [] CopyBack)位于C:\ Projects\WebBrowser\SampleCall.vb中的Execute() :第16行
这个问题有什么解决方案吗?
相同的代码适用于具有多个WebBrowser控件的vb6应用程序
编辑:此代码与以下内容混合:选项严格关闭
我们正在与C++ Builder 2010应用程序中的某些第三方COM对象进行交互.
目前,我们导入类型库并生成组件包装器,然后能够以相当自然的方式进行方法调用和访问属性.
object->myProperty = 42;
object->doSomething(666);
Run Code Online (Sandbox Code Playgroud)
但是,我们被COM对象的接口(仍在扩展和开发)的更改所困扰,导致我们自己的应用程序失败,因为某些方法GUID似乎无效 - 即使对接口的唯一更改是添加一种新方法).
后期绑定被认为是解决这个问题的一种方法.我认为这需要我们的代码更改,如下所示:
object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);
Run Code Online (Sandbox Code Playgroud)
显然这对于读写来说是痛苦的,所以我们必须编写包装类.
有没有办法在导入类型库时自动生成后期绑定包装器?并且,如果是这样,他们是否足够聪明,只能在创建对象时执行文本绑定,而不是每次调用方法?
我需要延迟绑定到3.5 C#应用程序中的第三方VB6 COM对象(以避免我们当前拥有的版本依赖项).由于某些错误在我们尝试正常使用时导致错误,因此提供的dll在大多数非后期方式中都不可使用.目前,我们正在使用一个自定义的VB6包装器,它使得VERY特定于版本,但是我发现我可以使用后期绑定来访问属性和方法.现在,我试图延迟绑定到事件,但是我读到的所有内容都说我需要从COM包装器的接口继承来创建所需的事件接收器.这是一篇这样的文章.
所以,我的问题是,是否有可能在编译时没有引用dll的情况下执行后期绑定事件处理?
UPDATE
以下是我对VB6包装器的错误(仍在积极更新).
无法反编译所选项目错误加载类型库/ DLL.TYPE_E_CANTLOADLIBRARY($ 80029C4A)
无法确定COM引用"3rdPartyDLL"的依赖项.加载类型库/ DLL时出错.(来自HRESULT的异常:0x80029C4A(TYPE_E_CANTLOADLIBRARY))
如何使用后期绑定设置Range.EntireColumn.NumberFormat?我目前有这个代码:
object rg = ws.GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, ws, new object[2]{1,iCol});
object ec = rg.GetType().InvokeMember("EntireColumn", BindingFlags.GetProperty, null, rg, null);
rg.GetType().InvokeMember("NumberFormat", BindingFlags.SetProperty, null, rg, new object[1] { "DD/MM/YYYY" });
Run Code Online (Sandbox Code Playgroud)
而且对于AutoFit方法,我有这个:
object rng = ws.GetType().InvokeMember("UsedRange", BindingFlags.GetProperty, null, ws, null);
object cols = rng.GetType().InvokeMember("Columns", BindingFlags.GetProperty, null, rng, null);
cols.GetType().InvokeMember("AutoFit", BindingFlags.InvokeMethod, null, cols, null);
Run Code Online (Sandbox Code Playgroud)
对于AutoFit,我不确定我是否做得很好.
想象一下以下假设的类结构,而不是一个非常罕见的场景,所有PHPdoc提示设置正确:
class BaseFilter {
/** ...base methods... */
}
class TextFilter extends BaseFilter {
public function setMinLength($len)
{
/** ...irrelevant */
}
}
class SomethingWithFilters
{
/**
* @param BaseFilter $filter A valid filter to be added.
* @return BaseFilter The filter that was added for easy chaining
*/
public function addFilter(BaseFilter $filter)
{
$this->filters[] = $filter;
return $filter;
}
/** @var BaseFilter[] A list of filters */
private $filters = [];
}
Run Code Online (Sandbox Code Playgroud)
现在我使用以下代码:
$myClass = new SomethingWithFilters();
$myClass->addFilter(new TextFilter())->setMinLength(8); …Run Code Online (Sandbox Code Playgroud) 我需要使用c#late binding features在运行时根据对象的类型调用方法重载.当所有重载都在调用发生的同一个类中定义时,它工作正常.但是当在派生类中定义重载时,它不会在运行时绑定.
class BaseT
{}
class DerivedA : BaseT
{}
class DerivedB : BaseT
{}
class Generator
{
public void Generate(IEnumerable<BaseT> objects)
{
string str = "";
foreach (dynamic item in objects)
{
str = str + this.Generate(item); //throws an exception on second item
}
}
protected virtual string Generate(DerivedA a)
{
return " A ";
}
}
class DerivedGenertor : Generator
{
protected virtual string Generate(DerivedB b)
{
return " B ";
}
}
class Program
{
static …Run Code Online (Sandbox Code Playgroud) 何时进行懒惰评估?(生成器,如果是迭代器?),什么时候延迟绑定?(关闭,常规功能?)
a = [1,2,3,4]
b = [lambda y: x for x in a]
c = (lambda y: x for x in a) #lazy evaluation
d = map(lambda m: lambda y:m, a) #closure
for i in b:
print i(None)
# 4 4 4 4
for i in c:
print i(None)
# 1 2 3 4
for i in d:
print i(None)
# 1 2 3 4
Run Code Online (Sandbox Code Playgroud) 我正在尝试运行我最初使用Visual Studio通过另一个不允许后期绑定的应用程序创建的代码,不幸的是这个选项无法更改.我对编程很新,并努力解决这个问题.这是我在调用代码阶段使用的代码:
Dim objIEShell As Object = CreateObject("Shell.Application")
Dim objIEShellWindows As Object = objIEShell.Windows
Dim objIEWin As Object
For Each objIEWin In objIEShellWindows
If InStr(objIEWin.LocationURL,"google")>0 Then
objIEWin.Quit
objIEWin = Nothing
End If
Next
Run Code Online (Sandbox Code Playgroud)
该代码只是在URL中使用"google"关闭所有Internet Explorer实例.这是我在尝试编译时得到的错误消息:
Message: Error compiling code
error BC30574: Option Strict On disallows late binding. At line 2
error BC32023: Expression is of type 'Object', which is not a collection type. At line 4
Run Code Online (Sandbox Code Playgroud)
从研究我迄今所做我认识的第一个错误消息,第2行是objIEShell和Windows之间的方法类型的差异做.我想我必须objIEShell像这样转换CType(objIEShell,?),但我不知道.Windows方法的类型或如何找到它.此外,任何关于如何修复第二个错误的见解都将受到极大的赞赏,因为我不知道从哪一个开始.