C# 尝试使用c调用COM对象上的方法时,“值不在预期范围内。”

C# 尝试使用c调用COM对象上的方法时,“值不在预期范围内。”,c#,com-interop,C#,Com Interop,我在尝试使用c调用COM对象上的方法时遇到异常 仅当我尝试调用该方法而不使用tlbimp.exe生成的COM运行时可调用包装RCW互操作程序集时,才会发生这种情况 当严格使用COM互操作程序集时,一切都可以完美地工作 我不想使用COM互操作程序集的原因是,目标计算机上的CLSID和PROGID可能与创建互操作程序集时不同,但方法名称、定义和结构相同 但是,在此测试中,COM服务器使用与运行时可调用包装RCW中定义的CLSID和PROGID相同的CLSID和PROGID进行注册,运行时可调用包装R

我在尝试使用c调用COM对象上的方法时遇到异常

仅当我尝试调用该方法而不使用tlbimp.exe生成的COM运行时可调用包装RCW互操作程序集时,才会发生这种情况

当严格使用COM互操作程序集时,一切都可以完美地工作

我不想使用COM互操作程序集的原因是,目标计算机上的CLSID和PROGID可能与创建互操作程序集时不同,但方法名称、定义和结构相同

但是,在此测试中,COM服务器使用与运行时可调用包装RCW中定义的CLSID和PROGID相同的CLSID和PROGID进行注册,运行时可调用包装RCW直接从运行的COM服务器程序集生成

在Windows 7 SP1 64位上运行。 C++ COM服务器是32位 C程序集是使用任何CPU和目标.NET Framework 4构建的

C++COM服务器IDL代码段:

[
object,
uuid(MyComObjectInterfaceGuid),
dual,
helpstring("MyComObject Interface"),
pointer_default(unique)
]
interface IMyComObject : IDispatch
{
    #import "MyCustomStruct.h"
    [id(110), helpstring("Method110")] HRESULT Method110([out] MY_CUSTOM_STRUCT *pMyCustomStruct);
}

[
uuid(MyComObjectGuid),
helpstring("MyComObject")
]
coclass MyComObject
{
    [default] interface IMyComObject;
};
MyCustomStruct.h:

#define MyCustomType2 MyCustomType;
#define long unsigned MyCustomType2;

typedef struct MY_CUSTOM_STRUCT
{
    bool            property1;
    MyCustomType    property2;
    wchar_t         property3[42];
    int             property4;
} MY_CUSTOM_STRUCT;
例如,注册COM服务器DLL时,rgs文件会插入ProgId注册表值

运行时可调用包装器生成以下结构:

public struct MY_CUSTOM_STRUCT
{
    public byte property1;
    public MyCustomType property2;
    public ushort[] property3;
    public int property4;
}

public struct MyCustomType
{
    public uint @value;
}
C代码段的工作原理:

using MyComObjectInteropNamespace;

MyComObject myComObject = new MyComObject();

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
myComObject.Method110(out myCustomStruct);

// myCustomStruct contains the expected values
引发异常的C代码段:

using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
object[] args = { myCustomStruct };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

object[] args = { new UnknownWrapper(null) };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
MY_CUSTOM_STRUCT myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
dynamic myComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Company.Product.MyComObject", true));

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
myComObject.Method110(out myCustomStruct); // exception is thrown here
例外情况:

System.ArgumentException occurred
  HResult=-2147024809
  Message=Value does not fall within the expected range.
  Source=mscorlib
  StackTrace:
       at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
       at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
  InnerException: 
System.ArgumentException occurred
  HResult=-2147024809
  Message=Value does not fall within the expected range.
  Source=mscorlib
  StackTrace:
       at System.Runtime.InteropServices.Marshal.GetNativeVariantForObject(Object obj, IntPtr pDstNativeVariant)
       at System.Dynamic.UnsafeMethods.InitVariantForObject(Object obj, Variant& variant)
  InnerException: null
也引发相同异常的C代码段:

using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
object[] args = { myCustomStruct };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

object[] args = { new UnknownWrapper(null) };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
MY_CUSTOM_STRUCT myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
dynamic myComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Company.Product.MyComObject", true));

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
myComObject.Method110(out myCustomStruct); // exception is thrown here
同时引发异常的C代码段:

using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
object[] args = { myCustomStruct };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
using MyComObjectInteropNamespace;

Type myComObjectType = Type.GetTypeFromProgID("Company.Product.MyComObject", true);
object myComObject = Activator.CreateInstance(myComObjectType);

object[] args = { new UnknownWrapper(null) };

ParameterModifier parameterModifier = new ParameterModifier(1);
parameterModifier[0] = true;
ParameterModifier[] parameterModifiers = { parameterModifier };

myComObjectType.InvokeMember( // exception is thrown here
    "Method110",
    BindingFlags.InvokeMethod,
    null,
    myComObject,
    args,
    parameterModifiers,
    null,
    null);

// code does not get this far
MY_CUSTOM_STRUCT myCustomStruct = (MY_CUSTOM_STRUCT)args[0];
dynamic myComObject = Activator.CreateInstance(Type.GetTypeFromProgID("Company.Product.MyComObject", true));

MY_CUSTOM_STRUCT myCustomStruct = new MY_CUSTOM_STRUCT();
myComObject.Method110(out myCustomStruct); // exception is thrown here
例外情况:

System.ArgumentException occurred
  HResult=-2147024809
  Message=Value does not fall within the expected range.
  Source=mscorlib
  StackTrace:
       at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
       at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
  InnerException: 
System.ArgumentException occurred
  HResult=-2147024809
  Message=Value does not fall within the expected range.
  Source=mscorlib
  StackTrace:
       at System.Runtime.InteropServices.Marshal.GetNativeVariantForObject(Object obj, IntPtr pDstNativeVariant)
       at System.Dynamic.UnsafeMethods.InitVariantForObject(Object obj, Variant& variant)
  InnerException: null

我也在MSDN论坛上发了帖子:

将你的财产3的长度也设置为42。谢谢,@Snake。我已经试过了,比如myCustomStruct.property3=new-ushort[42];,在调用Method110之前,我得到了相同的异常。