Welcome to MSDN Blogs Sign in | Join | Help

张羿的MSDN Blog

All about CLR/Interop, COM, Win32, C++

Syndication

#import从.NET DLL生成的Tlb的神秘错误

经常看到有朋友问到类似的问题,问题本身不复杂,但是答案不是特别明显,这里我把解决方法Post出来和大家共享一下,希望能够有所帮助。

假设我们有下面的A.cs文件:

using System;

using System.Runtime.InteropServices;

 

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

public interface IA

{

       Type Func();

}

 

[ComVisible(true)]

public class A : IA

{

       public Type Func()

       {

              return null;

             

       }

}

 

首先用CSC.exe编译为DLL文件,然后用TlbExp.exe生成对应的TLB (TypeLibrary)让下面的C++代码来引用之:

#import "a.tlb" no_namespace

 

void main(void)

{

       //

       // use class A...

       //

}

 

但是使用CL.exe编译的时候发生了如下错误:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86

Copyright (C) Microsoft Corporation.  All rights reserved.

 

t.cpp

d:\var\a.tlh(49) : error C2146: syntax error : missing ';' before identifier 'Fu

nc'

d:\var\a.tlh(49) : error C4430: missing type specifier - int assumed. Note: C++

does not support default-int

d:\var\a.tlh(49) : error C4430: missing type specifier - int assumed. Note: C++

does not support default-int

d:\var\a.tlh(49) : warning C4183: 'Func': missing return type; assumed to be a m

ember function returning 'int'

d:\var\a.tli(14) : error C2143: syntax error : missing ';' before 'IA::Func'

d:\var\a.tli(14) : error C2433: '_TypePtr' : 'inline' not permitted on data decl

arations

d:\var\a.tli(14) : error C4430: missing type specifier - int assumed. Note: C++

does not support default-int

d:\var\a.tli(14) : error C4430: missing type specifier - int assumed. Note: C++

does not support default-int

d:\var\a.tli(18) : error C2064: term does not evaluate to a function taking 2 ar

guments

 

错误发生在VC生成A.TLB对应的头文件(*.tlh)和实现文件(*.tli)中,这难道是VCBug

实际上答案很简单,这是因为A.TLB引用了mscorlib.tlb造成的。Mscorlib.NET Framework中的类型所对应的Type Library,常见的.NET类型基本上都包括在里面了。#import并没有能够自动处理这种引用关系,并自动#import mscorlib.tlb。因此,编译器抱怨无法找到.NET中的对应类型,这里出错的类型是_TypePtr,是_Type接口(对应Type类型)的智能指针类型。这个步骤需要你自己做。因此正确的代码如下:

// add this line

#import "mscorlib.tlb" no_namespace     

 

#import "a.tlb" no_namespace

 

void main(void)

{

       //

       // use class A...

       //

}

 

 

作者:      张羿(ATField)
Blog:     
http://blog.csdn.net/atfield
               
http://blogs.msdn.com/yizhang
转载请注明出处

Published Wednesday, March 05, 2008 2:53 PM by yzha

Filed under: , , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法 @ Tuesday, July 22, 2008 12:55 AM

CLR Interop简而言之是让非托管代码与托管代码之间可以相互调用的技术。这项技术可以使开发人员重用已有的托管或非托管组建,并根据自己的需要,权衡托管代码的简易性与非托管代码的灵活性,选择适合自己实际情况的编程语言,而不用过多考虑重用的组件是用哪种语言开发的。Interop中文的意思是互通性,既然是互通,代码的调用就有两种不同的方向。本文所要讲述的是使用COM

CLR & Silverlight上海研发团队的Blog

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
Page view tracker