C# #import referenced a type from a missing type library; '__missing_type__' used as a placeholder

StackOverflow https://stackoverflow.com/questions/22719714

  •  23-06-2023
  •  | 
  •  

سؤال

In C# assembly I created the following class/interface and generated a A.tlb

[ComVisible(true)]
[Guid("9850B8CE-B71E-4C77-ABE6-94BEB8EA308E")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ITest
{
    [DispId(1)]
    string Foo();

}

[ComVisible(true)]
[Guid("E9625332-FEB3-4B9D-AB01-9BAAF844F8F3")]
[ClassInterface(ClassInterfaceType.None)]
public class Test : ITest
{
    public string Foo()
    {
        return "hi";
    }

}

In another managed assembly I did created class/interface and generated a B.tlb

[ComVisible(true)]
[Guid("EF77F05A-B644-4E46-9AD9-5CB2E87EE89E")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IJunk
{
    ITest Foo();
}

[ComVisible(true)]
[Guid("D88BD554-4D58-49A2-9E0F-058D47CBE3CE")]
[ClassInterface(ClassInterfaceType.None)]
public class Junk : IJunk
{
    public ITest Foo()
    {
        var i = new Test();
        return i;

    }
}

Finally in a native C++ I did an #import B.tlb

I am getting

Error 2 error C4772: #import referenced a type from a missing type library; 'missing_type' used as a placehol

I saw this but it appeared to be straight C++ COM

Any way to resolve C4772 errors without having to register DLLs?

I tried to import A.tlb first and that didnt solve the problem

هل كانت مفيدة؟

المحلول

This went wrong because you skipped a required step. You must register A.dll with Regasm.exe before you try to generate B.tlb. This writes keys in the Typelib and Interface registry key. If you don't then Tlbexp cannot figure out that ITest is described by A.tlb and will omit the necessary importlib("A.tlb") directive in the type library for B. Which then makes the #import directive in the C++ compiler fall over since it cannot figure out where ITest comes from. #importing A.tlb first is not a workaround.

Other than running Regasm by hand, the simplest way to ensure this is done is by letting the build system take care of that. Right-click your A project, Properties, Build tab, tick the "Register for COM interop" option. VS however must run elevated to have registry write access.

Keeping the declarations in just one project avoids this problem.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top