S7 Kommandoschnittstelle mit VC++

Chefmech

Level-1
Beiträge
267
Reaktionspunkte
26
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein erster Test mit der Kommandoschnittstelle hat in VB ganz gut funktioniert, nur ist das Ding sehr langsam.
Also wollte ich testhalber mal mit VC++ (VisualStudio6) darauf zugreiffen, scheitere aber bereits am CoCreateInstance, welche GUID muss ich dem für das Interface ISimatic übergeben?

PS: Die beiden DLL's habe ich mittels Klassenassistent eingefügt, er hat mir dann je ein headerfile und ein cpp file pro dll erstellt, nur eben fehlen mir im Headerfile die Konstanten.

Code:
CLSID clsID;


HRESULT hr;    
ISimatic* pIFace;
    



CoInitialize(NULL); // absolutely essential: initialize the COM subsystem

    
const IID IID_ISimatic = __uuidof(ISimatic);    //--> Funktioniert nicht!!!


if (SUCCEEDED(hr = ::CLSIDFromProgID(L"Simatic.Simatic.1", &clsID))){

    hr = CoCreateInstance(clsID, NULL, CLSCTX_INPROC_SERVER, IID_ISimatic, (void **)&pIFace);        //--> Bei IID_ISimatic liegt das Problem...
}
 

CoUninitialize(); // cleanup COM after you're done using its services

Leider ist die Konstande IID_ISimatic nicht in der Dll definiert und der Ausdruck __uuidof(ISimatic) funktioniert nicht.
Ich hätte zwar die GUID aus der dll ( 9A853ACE-BA8E-11D1-BAD8-0060086A411D), aber wie muss ich die korrekt übergeben
 
Hallo Chefmech.
Ich denke der einfachere Weg geht über den Import der Typlib.
Diese liegt auch im S7Bin Verzeichnis, wie die DLL.

#import "s7abatcx.tlb" named_guids
using namespace SimaticLib;

Dadurch werden dir in deinem Release Verzeichnis auch die Dateien
s7abatcx.tli und .tlh angelegt.
In der .tlh Datei ist dann deine CLSID_Simatic definiert.

Dann einfach einen Smartpointer
ISimaticPtr m_pSimatic;
definieren, und mit
hr = m_pSimatic.CoCreateInstance( CLSID_Simatic ):
instanziieren.
mfg
Linus
 
Da hab ich mich wohl etwas übernommen, das Übersteigt wohl meine C-Kenntnisse :-(

Hast du mir ein kleines Beispiel, wie ich zb. alle Projektnamen auslesen kann?
Mein Code führt zu folgendem:

Code:
hr = m_pSimatic.CreateInstance ( CLSID_Simatic );
Nicht abgefangene Ausnahme in test5.exe (KERNEL32.DLL): 0xE06D7363: Microsoft C++ Exception.

Code:
nCntProj = s7Projects->GetCount();
AccessViolation...

Code:
s7Project = s7Projects->GetItem(&i);
Warum muss ich dem die Adr. von i übergeben anstatt (i)??? Ist wohl auch falsch, aber (i) akzeptiert er nicht...
-->GetName() wird wohl so auch nicht funktionieren...

Code:
void CTest5Dlg::OnButton1() 
{
    // TODO: Code für die Behandlungsroutine der Steuerelement-Benachrichtigung hier einfügen



    HRESULT hr;    
    ISimaticPtr m_pSimatic;
    IS7Projects *s7Projects;
    IS7Project *s7Project;
    CString sName;

    int nCntProj;
    
    CoInitialize(NULL); // absolutely essential: initialize the COM subsystem

    hr = m_pSimatic.CreateInstance ( CLSID_Simatic );

    s7Projects = m_pSimatic->GetProjects(); 
    
    nCntProj = s7Projects->GetCount(); 

    for(int i; i < nCntProj; i++){
        ;
        s7Project = s7Projects->GetItem(&i);
        sName = s7Project->GetName();

    };
    
    
    m_pSimatic.Release();
    CoUninitialize(); // cleanup COM after you're done using its services
    
}

PS: Als Projektart habe ich ein MFC (Dialogbasiert) gewählt...
 
Hallo,
folgender Code sollte in deinem Umfeld funktionieren:
Code:
void CS7KSSMinimalDlg::OnButton1() 
{
 // SmartPointer der Kommando-Schnittstelle
 ISimaticPtr   m_pSimatic;
 IS7ProjectsPtr  m_pProjects; 
 IS7Project3Ptr  m_pSingleProj; 
 HRESULT    hr;
 hr = CoInitialize( NULL );
 // create a single uninitialized object 
 hr = m_pSimatic.CreateInstance( CLSID_Simatic );
 hr = m_pSimatic->get_Projects( &m_pProjects );

 int     icount; 
 icount = m_pProjects->GetCount();

 VARIANT    vIndex;
 vIndex.vt = VT_I4;
 BSTR    bName;
 CString    csTest;
 for ( int iloop = 0; iloop < icount; iloop++ )
 {
  vIndex.lVal   = iloop + 1;
  m_pSingleProj = m_pProjects->GetItem( vIndex );
  bName = m_pSingleProj->GetName();
  csTest = bName;
  SysFreeString( bName );  
 }
 
 CoUninitialize();
}

Zu Beachten:
Jeder der nicht raw Funktionen kann eine exception werfen, die aufgefangen werden muss.
Oder du nimmst die raw Funktionen. Siehe als Beispiel get_Projects() und GetProjects()
Warum bei dir die erste exception bereits beim createinstance kommt, muss von deinem
Rechner abhängen, das obige Beispiel läuft bei mir.
mfg
Linus
 
Zurück
Oben