I am trying to make a COM object so I can use my C# object in a C++ project. I have been following this example, to the point where everything is almost identical, but however much I try I can't get it to work.

Here is my C# program:

// CSharpServer.cs
// compile with: /target:library
// post-build command: regasm CSharpServer.dll /tlb:CSharpServer.tlb

using System;
using System.Runtime.InteropServices;
namespace CSharpServer
{
    // Since the .NET Framework interface and coclass have to behave as 
    // COM objects, we have to give them guids.
    [Guid("23E401BD-A533-4abf-B1E2-D6466B6869C0")]
    public interface IManagedInterface
    {
        int PrintHi(string name);
    }

    [Guid("E28BA761-E40D-40d6-B691-366577D22A78")]
    public class InterfaceImplementation : IManagedInterface
    {
        public int PrintHi(string name)
        {
            Console.WriteLine("Hello, {0}!", name);
            return 33;
        }
    }
}

with the checkbox "Register for COM interop" true and the post build events:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm "C:\Users\tofuser\Documents\Visual Studio 2008\Projects\CSharpServer\bin\Debug\CSharpServer.dll" /tlb "C:\Users\tofuser\Documents\Visual Studio 2008\Projects\CSharpServer\bin\Debug\CSharpServer.tlb"

My C++ code:

// To use managed-code servers like the C# server, 
// we have to import the common language runtime:
#import <mscorlib.tlb> raw_interfaces_only

#import "C:\Users\tofuser\Documents\Visual Studio 2008\Projects\CSharpServer\bin\Debug\CSharpServer.tlb" no_namespace named_guids

int main(int argc, char* argv[])
{
   IManagedInterface *cpi = NULL;

   int retval = 1;

   // Initialize COM and create an instance of the InterfaceImplementation class:
   CoInitialize(NULL);
   HRESULT hr = CoCreateInstance(CLSID_InterfaceImplementation,
               NULL, CLSCTX_INPROC_SERVER,
               IID_IManagedInterface, reinterpret_cast<void**>(&cpi));

   if (FAILED(hr))
   {
      printf("Couldn't create the instance!... 0x%x\n", hr);
   }
   else
   {
      if (argc > 1)
      {
         printf("Calling function.\n");
         fflush(stdout);
         // The variable cpi now holds an interface pointer 
         // to the managed interface.
         // If you are on an OS that uses ASCII characters at the 
         // command prompt, notice that the ASCII characters are 
         // automatically marshaled to Unicode for the C# code.
         if (cpi->PrintHi(argv[1]) == 33)
            retval = 0;
         printf("Returned from function.\n");
      }
      else
         printf ("Usage:  COMClient <name>\n");
      cpi->Release();
      cpi = NULL;
   }

   // Be a good citizen and clean up COM:
   CoUninitialize();
   return retval;
}

It loads the library fine, but I get the following errors:

1>COMClient.cpp(22) : error C2065: 'IManagedInterface' : undeclared identifier
1>COMClient.cpp(22) : error C2065: 'cpi' : undeclared identifier
1>COMClient.cpp(27) : error C2065: 'CLSID_InterfaceImplementation' : undeclared identifier
1>Project : error PRJ0019: A tool returned an error code from "Performing Pre-Build Event..."
1>COMClient.cpp(29) : error C2065: 'IID_IManagedInterface' : undeclared identifier
1>COMClient.cpp(29) : error C2065: 'cpi' : undeclared identifier
1>COMClient.cpp(46) : error C2065: 'cpi' : undeclared identifier
1>COMClient.cpp(46) : error C2227: left of '->PrintHi' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>COMClient.cpp(52) : error C2065: 'cpi' : undeclared identifier
1>COMClient.cpp(52) : error C2227: left of '->Release' must point to class/struct/union/generic type
1> type is ''unknown-type''
1>COMClient.cpp(53) : error C2065: 'cpi' : undeclared identifier


I'm really stuck, thanks for any help.

Edited 6 Years Ago by hanvyj: n/a

I noticed there is a "compile with: /target:library" comment, how do I "compile with"?

Found it!

There is a well hidden option, other than "Register for COM interop" called "Make Assembly COM visable" in properties->Application->AssemblyInformation

It works now!

Found it!

There is a well hidden option, other than "Register for COM interop" called "Make Assembly COM visable" in properties->Application->AssemblyInformation

It works now!

This question has already been answered. Start a new discussion instead.