Click here to Skip to main content
15,911,646 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using c# with wpf to create a class library, I am exporting this as COM interface. I am trying to call this com object from plain C. I have managed to get it working in C++ but am struggling to get it working in plain C.

so I am using the follwing code in c# to create the com interface.
C#
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Linq;
using System.Text;


namespace WPF_TEST
{
    [ComVisible(true)]
    [Guid("92ce2a56-c61f-486c-8854-4d8d88626ba9")]
    public interface ITestWPFInterface
    {
        [DispId(1)]
        void TestWPF();
    }
    [ComVisible(true)]
    [Guid("62e2ed3c-5c2a-48c5-851b-e0b1f6daa9cd"),
    ClassInterface(ClassInterfaceType.None)]

    public class TestWPFInterface : ITestWPFInterface
    {
        public void TestWPF()
        {
            WPF_TEST.MainWindow window = new WPF_TEST.MainWindow();
            window.ShowDialog();
        }


    }

}  

this code is then packaged into a class library and "register for com interop" is ticked.

I am following the jeff glatt tutorial using the following code in plain c to try and pick up this COM object
Header file
C++
#ifndef _ITESTWPFINTERFACE_H_
#define _ITESTWPFINTERFACE_H_

#include <initguid.h>


// Our IExample object's GUID
// original {6899A2A3-405B-44d4-A415-E08CEE2A97CB}
// porting guid ("62e2ed3c-5c2a-48c5-851b-e0b1f6daa9cd")
DEFINE_GUID(CLSID_ITestWPFInterface, 0x62e2ed3c, 0x5c2a, 0x48c5, 0x85, 0x1b, 0xe0, 0xb1, 0xf6, 0xda, 0xa9, 0xcd);

// Our IExample VTable's GUID
// original {74666CAC-C2B1-4fa8-A049-97F3214802F0}
// porting Guid("92ce2a56-c61f-486c-8854-4d8d88626ba9")
DEFINE_GUID(IID_ITestWPFInterface, 0x92ce2a56, 0xc61f, 0x486c, 0x88, 0x54, 0x4d, 0x8d, 0x88, 0x62, 0x6b, 0xa9);

// Defines IExample's functions (in a way that works both for our COM DLL
// and any app that #include's this .H file
#undef  INTERFACE
#define INTERFACE   ITestWPFInterface

/*PROBLEM HERRREEEEE */

DECLARE_INTERFACE_ (INTERFACE, IUnknown)
{
   STDMETHOD  (QueryInterface)      (THIS_ REFIID, void **) PURE;
   STDMETHOD_ (ULONG, AddRef)       (THIS) PURE;
   STDMETHOD_ (ULONG, Release)      (THIS) PURE;
   STDMETHOD  (TestWPF)         (THIS) PURE;

};

#endif 


C file

i initialise and get as far as creating the instance and releasing the class factory
#include <stdio.h>
#include <windows.h>
#include <objbase.h>
#include "ITestWPFInterface.h"

int main( int argc, const char* argv[] )
{
	ITestWPFInterface		*exampleObj;
	IClassFactory	*classFactory;
	HRESULT			hr;
   HRESULT			hres;
   int result;
   if (!CoInitialize(0))
	{
          result = GetLastError();
          // Get WPF.DLL's IClassFactory
	  if ((hr = CoGetClassObject(&CLSID_ITestWPFInterface,CLSCTX_INPROC_SERVER,0,&IID_IClassFactory,&classFactory)))

MessageBox(0, "Can't get IClassFactory", "CoGetClassObject error", MB_OK|MB_ICONEXCLAMATION);
      else
		{
        
			// Create a wpf object
	     if ((hr = classFactory->lpVtbl->CreateInstance(classFactory,0,&IID_ITestWPFInterface,&exampleObj)))
			{
		classFactory->lpVtbl->Release(classFactory);
				MessageBox(0, "Can't create ITestWPFInterface object", "CreateInstance error", MB_OK|MB_ICONEXCLAMATION);
			}
         else
         {
           result = GetLastError();
            // Release the IClassFactory. We don't need it now that we have the one
				hr  =classFactory->lpVtbl->Release(classFactory);
          
            // HERE IS WHERE THE PROBLEM OCCURS RETURNS A E_POINTER
            // the com object definitely is available as i have accessed it from a C++ project
           // Call SetString to set the test wpf
           hres = exampleObj->lpVtbl->TestWPF(exampleObj);
           
           
           
           // Release the com now that we're done with it
          
           exampleObj->lpVtbl->Release(exampleObj);
          
         }
         
      }
               // When finally done with OLE, free it
		CoUninitialize();
	}
       else
		MessageBox(0, "Can't initialize COM", "CoInitialize error", MB_OK|MB_ICONEXCLAMATION);
	        return(0);


}
// this builds ok but this returns an E_POINTER error and I get an error that says that 'The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.'

ANY IDEAS?
Posted
Updated 14-Jul-11 7:07am
v7

Hi I compiled as C as it was a requirement. I tested the COM object in c++ and it worked fine. I wanted to see if it was possible in C. After trying for a day and a half I gave up. I ended up implementing in C++ and wrapping the functions.

Here is my c++ code that just opens the wpf window
<pre lang="cs">
#import name.tlb
.
.
.
.
 
int WPF_Com::Initialise()
{

   if(CoInitialize(NULL) == S_OK)
{

   initialised =1;
   WPF_TEST::ITestWPFInterfacePtr comInterface(__uuidof(WPF_TEST::TestWPFInterface));

   comInterface->;TestWPF();
   CoUninitialize();

    return initialised;
}
else 
return -1;
}



Here is my C to provide wrappers to CPP functions

<pre lang="midl">WPF_Com *pWPF = NULL;

extern "C" /*Provide C wrappers to CPP functions*/
{
/*+
************************************************************************
*
*  function    : wpf_com_open()
*
*  description : Open WPF using COM interface
*
*  arguments   : void
*
*  returns     : int
*
***********************************************************************
-*/
int wpf_com_open()
{
   if ( pWPF == NULL )
   {
      pWPF = new WPF_Com(true);
      if ( pWPF )
      {
         pWPF->Initialise();
      }
   }
return 0;
}



I then called wpf_com_open from the main body of my application.

I hope this helps someone out there

:)
 
Share this answer
 
my experience on COM is that the messages are fully right, but hard to understand. So i think that your marshalling or some other option isnt complety right. Make a test program in C# to test that the COM object is working fine.

Why dont you compile as C++?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900