troubleshooting Question

How can I call a method from within a C++ Win32 application?

Avatar of 3mCanada
3mCanadaFlag for Canada asked on
CC++.NET Programming
4 Comments1 Solution327 ViewsLast Modified:
I have a single function written in that I need to call from a C++ program.  (It is a complex function that processes an excel spreadsheet; recoding it into c++ would be non-trivial.)  What would be the best way to achieve this?  I have to pass multiple parameters both ways.

I tried executing the following sample program listed in question ID: 9807676, but could not get it to work.  
The VB code built OK, and the sn..., regasm... and gacutil... command line calls claimed the succeeded.  

The C code would not compile as posted, listing 'AClass' in the following line as an undeclared identifier.
           pIAClass.CoCreateInstance( __uuidof( AClass ) );   // Create the object
Changing 'AClass' to 'IAClass' allowed it to compile OK, (though that was just a guess at how to fix it.)
However, the pIAClass.CoCreateInstance... call fails at runtime with error code REGDB_E_CLASSNOTREG.  

Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices

<Assembly: AssemblyKeyFile( "mykey.snk" )>

< ComVisible( true ) > _
Public Interface IAClass
      Function GetCurrentTime() As String
End Interface

< ProgId( "MyCompany.MyLib.AClass" ) > _
Public Class AClass
      Implements IAClass

      Public Function GetCurrentTime() As String Implements IAClass.GetCurrentTime
            Return System.DateTime.Now.ToString()
      End Function
End Class

To compile the MyLib.vb file:
sn -k mykey.snk
vbc /t:library MyLib.vb

Then to "deploy" (register it with COM to make it available for import in C++)
regasm /tlb:MyLib.tlb MyLib.dll
gacutil -i MyLib.dll

(1st we register it in the COM registry, and ask for a .tlb file to use with our Cpp code)
(2nd we make the Assembly global so that any instantiation can find it)

Now onto our Cpp code:
#include <windows.h>
#include <atlbase.h>
#include <stdio.h>

#import "./Mylib.tlb"  // import the tlb we generated previously

int main()
      CoInitialize( 0 );   // Initialize COM
            using namespace MyLib;    // save us from the trouble of always doing MyLib::IAClass, etc...

            CComPtr< IAClass > pIAClass;
            pIAClass.CoCreateInstance( __uuidof( AClass ) );   // Create the object

            _bstr_t bstrResult = pIAClass->GetCurrentTime();  // Call our .NET func and get the result

            printf( "Current DateTime: %s\n", (char*)bstrResult );

compiling this is trivial:
cl MyApp.cpp
Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 4 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 4 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros