Programm läuft mit MSVC6, aber nicht mit MSVS.NET2003



  • Wenn man sich zum Vergleich mal die comip.h vom VC6 anschaut, dann gibt es eigentlich keine Unterschiede:

    // Loads an interface for the provided CLSID.
    	// Returns an HRESULT.  Any previous interface is released.
    	//
    	HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
    	{
    		HRESULT hr;
    
    		_Release();
    
    		if (dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
    			IUnknown* pIUnknown;
    
    			hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
    
    			if (FAILED(hr)) {
    				return hr;
    			}
    
    			hr = OleRun(pIUnknown);
    
    			if (SUCCEEDED(hr)) {
    				hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
    			}
    
    			pIUnknown->Release();
    		}
    		else {
    			hr = CoCreateInstance(rclsid, pOuter, dwClsContext, GetIID(), reinterpret_cast<void**>(&m_pInterface));
    		}
    
    		return hr;
    	}
    

    Auch GetIID() sieht hier genauso aus.

    Wenn Du Zugriff auf einen VC6 hast, dann könntest Du mal versuchen, in beiden IDEs schrittweise durch die Funktionen zu laufen und zu schauen, ob es bei den Argumenten bzw. Rückgabewerten Unterschiede gibt.



  • Schau doch mal im Debugger welchen Wert reinterpret_cast<void**>(&m_pInterface) hat, wenn QueryInterface() betreten wird.


  • Mod

    Ich kann m it nicht vorstellen, dass es hier einen Unterschied gibt, außer VC6 ermittelt eine andere Interface-ID als VC2003.

    Der Fehler liegt in keinem Fall auf der C++/MFC/ATL Seite. S_NOINTERFCAE bedeutet: Da ist ein COM-Objekt, aberdas Interface, nachdem Du fragst ist nicht vorhanden.
    Gib mal die IID direkt an!



  • Also an RTTI für reinterpret_cast liegts nicht, das hab ich probiert. &m_pInterface hat den Wert 0x00000000, was Martins Aussage, dass kein Interface vorhanden ist, stützt, vermute ich mal.
    GetIID() liefert folgendes:

    GetIID	0x00402190 _com_ptr_t<_com_IIID<OrgApplication::IOApplication,&_GUID_91186b48_39f5_11d3_9367_00c04f79eafe> >::GetIID(void)	const _GUID & (void)
    

    Nützt euch das was? Wie gesagt ich versteh selbst nicht mehr was ich hier mache... 😕

    Edit: Das mit RTTI bezog sich auf Jencas Post, aber das hat er inzwischen wegeditiert, also nicht wundern...


  • Mod

    Diese Info nützt Dir nichts, außer, dass Du jetzt weißt welche IID verwendet wird oder verlangt wird. Die Frage wäre einfach ob wirklich beide Interfaces identisch sind.

    Woher bekommst Du "Application"? Durch einen #import?
    Wird wirklich die selbe DLL, TLB, IDL verwendet?



  • Martin Richter schrieb:

    Woher bekommst Du "Application"? Durch einen #import?

    Ich glaube ja, es wird zumindest eine externe Bibliothek verwendet. Aber ich habe keine Ahnung, was da drinsteht, deswegen bin ich mir nicht wirklich sicher. Gibts eigentlich einen Weg, sowas rauszufinden? Zur Sicherheit hier nochmal die ganze Klasse:

    /*------------------------------------------------------------------------------*
     * File Name: OriginClient.cpp													*
     * Creation:  LY 4/7/2004														*
     * Purpose: Implementation of utility functions to access Origin Automation		*
     *			server																*
     * Copyright (C) OriginLab Corp.												*
     * All Rights Reserved															*
     *------------------------------------------------------------------------------*/
    
    #include "StdAfx.h"
    #include ".\originclient.h"
    
    #pragma comment(lib, "comsupp.lib")
    
    COriginClient::COriginClient(int nOption)
    {
    	//Initialize COM
    	CoInitialize(NULL);
    
    	//Create instance of Origin
    	HRESULT hr = 0;
    	switch( nOption )
    	{
    		case USE_EXIST_FIRST:
    			hr = m_pOApp.CreateInstance( __uuidof(ApplicationSI) );
    			break;
    
    		case ALWAYS_CREATE_NEW:
    		default:
    			hr = m_pOApp.CreateInstance( __uuidof(Application) );
    			break;
    	}
    }
    
    COriginClient::~COriginClient(void)
    {
    	//Release the created instance of Origin
    	if( m_pOApp != NULL )
            m_pOApp.Release();		
    
    	//Uninit COM
    	CoUninitialize();
    }
    
    BOOL COriginClient::IsValid()
    {
    	return (m_pOApp != NULL);
    }
    
    BOOL COriginClient::GetWorksheet(LPCSTR lpszWks, _variant_t& val)
    {
    	BOOL bRet = FALSE;
    	if( m_pOApp == NULL )
    		return bRet;
    
    	try
    	{
    		val = m_pOApp->GetWorksheet( _bstr_t(lpszWks) );
    		bRet = TRUE;
    	}
    	catch(...)
    	{
    		TRACE("ERROR during Origin access");
    		bRet = FALSE;
    	}	
    
    	return bRet;
    }
    
    BOOL COriginClient::SetWorksheet(LPCSTR lpszWks, _variant_t val, int nRowStart)
    {
    	BOOL bRet = FALSE;
    	if( m_pOApp == NULL )
    		return bRet;
    
    	_variant_t valRowStart;
    	valRowStart.vt = VT_I4;
    	valRowStart.intVal = nRowStart;
    
    	try
    	{
    		bRet = m_pOApp->PutWorksheet( _bstr_t(lpszWks), val, valRowStart );			
    	}
    	catch(...)
    	{
    		TRACE("ERROR during Origin access");
    	}
    
    	return bRet;
    }
    

    Und das Headerfile noch dazu:

    /*------------------------------------------------------------------------------*
     * File Name: OriginClient.h													*
     * Creation:  LY 4/7/2004														*
     * Purpose: Utility functions to access Origin Automation server				*
     * Copyright (C) OriginLab Corp.												*
     * All Rights Reserved															*
     *------------------------------------------------------------------------------*/
    
    #include "comdef.h"
    #include "comutil.h"
    
    #pragma once
    
    #import ".\Origin.tlb" rename_namespace("OrgApplication")
    using namespace OrgApplication;
    
    #define IS_VALID_ORIGIN_PTR(_p)		( _p != NULL && _p->IsValid() )
    #define ORIGIN_WINTYPE_WKS		2
    
    enum {
    	ALWAYS_CREATE_NEW = 0,
    	USE_EXIST_FIRST
    };
    
    class COriginClient
    {
    public:
    	COriginClient(int nOption = USE_EXIST_FIRST);
    	~COriginClient(void);
    
    public:
    	// This demonstrates how to wrap automation methods and provide
    	// user specified calling arguments
    	BOOL GetWorksheet(LPCSTR lpszWks, _variant_t& val);
    	BOOL SetWorksheet(LPCSTR lpszWks, _variant_t val, int nRowStart = 0);
    
    	//Method to assert the reference to Origin automation server is valid
    	BOOL IsValid();
    
    	// This demonstrates how to allow this class to be used 
    	// as the IOApplicationPtr itself.
    	IOApplicationPtr operator->() const 
    	{ 
    		if( m_pOApp == NULL ) 
    		{
    			_com_issue_error(E_POINTER);
    		}
    
    		return m_pOApp; 
    	}
    
    private:
    	IOApplicationPtr m_pOApp;
    };
    

  • Mod

    Bist Du sicher, dass sich hier

    #import ".\Origin.tlb" rename_namespace("OrgApplication")
    

    Auf die selbe Datei bezogen wird?



  • Ähm ich steh grad aufm Schlauch...was meinst du mit "auf die selbe Datei"?
    Meinst du, ob für das schon kompilierte Binary und meine eigene Kompilierung die selbe Datei verwendet wurde?


  • Mod

    Origin.tlb ist die Datei aus der die Interface-Definitionen kommen!

    Woher ist die, wer hat die erzeugt. Ist es garantiert die selbe, wie im VC6 Projekt?



  • Die Origin.tlb wird vom Hersteller mitgeliefert zu den Klassen für den Zugriff. Ein Mitarbeiter hat mir einen kompletten Projektordner geschickt, u.a. mit einer bereits von ihm kompilierten Debug- und ReleaseVersion. Seine Binaries kann ich ausführen, selbst kompilieren geht auch hier nicht, wie gehabt. In diesem Fall hab ich ja definitiv eine korrekte Origin.tlb verwendet 😕



  • Also ich habe jetzt auf meinem Notebook VC++6 installiert, den Quelltext dort kompiliert. Und siehe da, er lief auf meinem PC auf Arbeit, und tat genau das, was er sollte.
    Kann sich das jemand erklären?


Anmelden zum Antworten