2011-01-25 28 views
6

Tôi có hai lớp .NET được tiếp xúc qua COM interop - giả sử Foo và Bar, và tôi cần chuyển đối số kiểu Foo thành một phương thức được định nghĩa trong Bar. Một cái gì đó như thế này:Qua các đối số được gõ mạnh trong .NET COM interop

[ComVisible(true)] 
public class Foo 
{ 
    // whatever 
} 

[ComVisible(true)] 
public class Bar 
{ 
    public void Method(Foo fff) 
    { 
     // do something with fff 
    } 
} 

Khi tôi chạy sau VBS (sử dụng cscript.exe):

set foo = CreateObject("TestCSProject.Foo") 
set bar = CreateObject("TestCSProject.Bar") 
call bar.Method(foo) 

tôi nhận được một lỗi:

D:\test.vbs(3, 1) Microsoft VBScript runtime error: Invalid procedure call or argument: 'bar.Method'

Tuy nhiên, nếu tôi thay đổi tuyên bố Phương thức cho điều này:

public void Method(object o) 
    { 
     Foo fff = (Foo)o; 
     // do something with fff 
    } 

mọi thứ hoạt động. Tôi đã thử một số phép thuật với giao diện, thuộc tính, vv nhưng không may mắn cho đến nay.

Bất kỳ thông tin chi tiết nào?

Rất cám ơn

+0

Nó sẽ hoạt động như được đăng, VBScript sử dụng kết buộc muộn. Cố gắng cải thiện đoạn mã của bạn để tạo một ví dụ không theo cùng một cách. –

+0

@Hans - Tôi đã thêm đoạn mã VBS bị lỗi. Tất cả mọi thứ được sao chép/dán từ mã thực. Cảm ơn – Elephantik

Trả lời

6

Đảm bảo, bạn xác định thuộc tính GUID, điều này là cần thiết nếu bạn thực hiện QueryInterface (VB có thể). Bạn phải tạo một GUID duy nhất cho mọi lớp ẩn.

[Guid("77777777-3333-40df-9C0D-2B580E7E1F3B")] 
[ComVisible(true)] 
public class Foo 
{ 
} 

Sau đó, tôi khuyên bạn nên viết giao diện cho đối tượng COM của bạn và đặt ClassInterface thành None, vì vậy không có nội bộ nào được tiết lộ. Typelibrary của bạn sẽ được sạch hơn nhiều theo cách này.

[Guid("88888888-ABCD-458c-AB4C-B14AF7283A6B")] 
[ComVisible(true)] 
public interface IFoo 
{ 
} 

[ClassInterface(ClassInterfaceType.None)] 
[Guid("77777777-3333-40df-9C0D-2B580E7E1F3B")] 
[ComVisible(true)] 
public class Foo : IFoo 
{ 
} 
+0

VB không truy vấn giao diện cụ thể. Nó sử dụng 'IDispatch'. Dù sao, vấn đề ở đây là trong cách tham số 'Foo' được sắp xếp. – Ran

+0

@Ran Với marshalling nó như IUnknown bạn đang làm giống như Elephantik đã làm với tuyên bố các tham số như đối tượng, mà làm việc nhưng đó là không gõ mạnh. IDispatch trực tiếp kế thừa từ IUnknown, vì vậy VB có thể sử dụng QueryInterface khi yêu cầu một giao diện cụ thể (hoặc lớp). – martinstoeckli

+0

Thực ra, tôi đã làm điều đó. Tạo giao diện, GUIDed tất cả mọi thứ, nhưng không có may mắn. Tôi chỉ không muốn làm ngập mã nguồn. – Elephantik

2

Sau khi đấu tranh với cùng một vấn đề này trong một thời gian, tôi thấy rằng đang gặp sự cố khi chuyển tham chiếu thay vì theo giá trị. Xem ở đây:

http://msdn.microsoft.com/en-us/library/ee478101.aspx

Vì vậy, tôi chỉ cần thêm dấu ngoặc tròn để lập luận thông qua trong VB Script, và nó dường như đã giải quyết được vấn đề. Vì vậy, trong ví dụ của bạn, chỉ cần thực hiện việc này:

Set foo = CreateObject("TestCSProject.Foo") 
Set bar = CreateObject("TestCSProject.Bar") 
Call bar.Method((foo)) 

Nên hoạt động như mong đợi, không cần phải đặt thuộc tính ClassInterface và không sử dụng Giao diện.

Các vấn đề liên quan