有两个相同的COM对象定义。
F#版本,WebUIPlugin项目:
namespace WebUIPlugin
open System
open System.Runtime.InteropServices
[<Guid("BAEF0C5B-EFA5-4868-8342-7A1E6F8F7AF4")>]
type IPlugin =
[<DispId(1)>]
abstract OpenFormFromFile : path:string -> unit
[<Guid("8D71E2DB-D718-4595-B856-58D14EEAEBB2");
ClassInterface(ClassInterfaceType.None);
ComVisible(true)>]
type Plugin() = class
interface IPlugin with
member this.OpenFormFromFile(path) = ()
end
end
C#版本,WebUIPlugin2项目:
using System;
using System.Runtime.InteropServices;
namespace WebUIPlugin
{
[Guid("BAEF0C5B-EFA5-4868-8342-7A1E6F8F7AF4")]
public interface IPlugin
{
[DispId(1)]
void OpenFormFromFile(string path);
}
[Guid("8D71E2DB-D718-4595-B856-58D14EEAEBB2")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Plugin : IPlugin
{
public void OpenFormFromFile(string path)
{
}
}
}
项目设置相同。
虽然C#定义运行良好,但F#版本失败并带有
mscorlib.dll中发生了
System.MissingMethodException
类型的未处理异常 其他信息:试图访问失踪成员。
当我尝试按如下方式调用成员时(Example2项目):
class Program
{
static void Main(string[] args)
{
var objectType = Type.GetTypeFromProgID("WebUIPlugin.Plugin");
dynamic handler = Activator.CreateInstance(objectType);
objectType.InvokeMember("OpenFormFromFile", BindingFlags.InvokeMethod, null, handler, new object[]{""});
}
}
汇编:
CALL "c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat"
MSBuild.exe WebUIPlugin.sln /nologo /target:Build /p:Configuration=Debug /p:Platform="x64"
注册:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /codebase /verbose WebUIPlugin\bin\x64\Debug\WebUIPlugin.dll
测试:
C:\...\> Example2\bin\x64\Debug\Example2.exe
Unhandled Exception: System.MissingMethodException: Method 'WebUIPlugin.Plugin.OpenFormFromFile' not found.
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at CallSite.Target(Closure, CallSite, Type, String, BindingFlags, Object, Object, Object[])
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid6[T0,T1,T2,T3,T4,T5](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
at Example2.Program.Main(String[] args) in ...\Example2\Program.cs:line 16
注册C#版本:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe /codebase /verbose WebUIPlugin2\bin\x64\Debug\WebUIPlugin2.dll
测试:
C:\...\> Example2\bin\x64\Debug\Example2.exe
工作正常
答案 0 :(得分:2)
嗯,它将成为F#如何实现接口的问题。接口的实现方式只能通过接口本身调用,而不能通过类调用。
以下代码有效:
var objectType = Type.GetTypeFromProgID("WebUIPlugin.Plugin");
var handler = Activator.CreateInstance(objectType);
var types = objectType.FindInterfaces((_1, _2) => true, null);
var iPlugin = types.First(t => t.Name == "IPlugin");
iPlugin.InvokeMember("OpenFormFromFile", BindingFlags.InvokeMethod, null, handler, new object[]{""});
为了使它工作,F#接口也应该是ComVisible。