Programmieren mit C++

Borland C++

MFC mit BC++ benutzen

MFC 2.0 mit BC++ benutzen

Der folgende Tip zeigt auf, wie die Microsoft Foundation Class (MFC) 2.0 mit Borland C++ 3.1 und analog dazu 4.x verwendet werden kann.

Damit die MFC mit BC++ kompiliert und benutzt werden kann, sind mehrere Änderungen erforderlich, die teilweise auf die Non-Standard-Syntax der MFC und teilweise auf Unterschiede in den Assembler-Erweiterungen und Makefile-Konventionen zurückzuführen sind.

Änderungen an der MFC

Zur Nutzung mit BC++ müssen folgende MFC-Quellen geändert werden:

  • OBJCORE.CPP
  • AFX.INL
  • AFXCOLL.H
  • AFXOLE.H
  • AFXPRIV.H
  • AFXDLGS.H
  • AFXEXT.H
  • AFXWIN.H
  • AFX.H
  • AFXPEN.H

Alle Änderungen an den MFC-Files werden durch ein PreProcessor-Statement eingeschlossen, um sicherzustellen, daß das Makro __BORLANDC__ definiert ist. Damit ist garantiert, daß die Änderungen nur dann wirksam werden, wenn die Quellen mit dem Borland C++ Compiler kompiliert werden.

Ein Großteil der Änderungen erfolgt über eine neue Header-Datei AFX4BC.H. Die vollständige Datei ist auf der CD enthalten und soll hier nicht noch einmal wiederholt werden.

Modifikation von OBJCORE.CPP

In der Datei OBJCORE.CPP sind mehrere Änderungen vorzunehmen. Die erste Änderung betrifft die Funktion AfxAssertValidObject(), die auf near vptrs umgestellt werden muß, sofern nicht permanent far vtables benutzt werden:

#ifdef _DEBUG
extern "C" void AFXAPI AfxAssertValidObject(const CObject* pOb,
    LPCSTR lpszFileName, int nLine)
{
 if (pOb == NULL)  {
  TRACE0("ASSERT_VALID fails with NULL pointer\n");
  AfxAssertFailedLine(lpszFileName, nLine);
  return;     // quick escape
 }
 if (!AfxIsValidAddress(pOb, sizeof(CObject)))  {
  TRACE0("ASSERT_VALID fails with illegal pointer\n");
  AfxAssertFailedLine(lpszFileName, nLine);
  return;     // quick escape
 }
#ifndef _M_I86SM
#if !defined(__BORLANDC__)
 ASSERT(sizeof(CObject) == sizeof(void FAR*));
#endif

Die nächste Modifikation betrifft nur die near Data-Modelle und kann entfallen, wenn nur Compact- und Large-Speichermodelle verwendet werden. Ansonsten ist die Funktion CRuntimeClass::ConstructObject() wie folgt zu ändern:

BOOL CRuntimeClass::ConstructObject(void* pThis)
{
#if defined(__BORLANDC__)
  ASSERT(AfxIsValidAddress((const void FAR*)pThis, nObjectSize));
#else
 ASSERT(AfxIsValidAddress(pThis, nObjectSize));
#endif

Die letzte Änderung ist in der Funktion AfxInitialize() erforderlich. Es wird ein Cast hinzugefügt, da AfxNewHandler() nicht auf den Parametertyp von _AfxSetNewHandler() paßt.

static BOOL AfxInitialize()
{
 (void)_afx_version();
#ifdef _DEBUG
for CodeView
 (void)afxTraceEnabled;
 (void)afxMemDF;
#ifdef _WINDOWS
 (void)afxTraceFlags;
#endif
 if (!AfxDiagnosticInit())
  return FALSE;
#endif //_DEBUG
 
#if defined(__BORLANDC__)
  _AfxSetNewHandler( ( void (*)() ) 
                     AfxNewHandler );
#else
 _AfxSetNewHandler(AfxNewHandler);
#endif
 return TRUE;
}

Änderungen in AFX.INL

Da BC++ den _segname Modifier nicht unterstützt, muß die Funktion _AfxGetPtrFromFarPtr() wie folgt geändert werden. Dabei ist zu beachten, daß der neue Code nicht mehr verifiziert, ob der far-Zeiger auf _DATA zeigt.

AFX_INLINE void* PASCAL _AfxGetPtrFromFarPtr(void FAR* lp)
{
#ifdef _NEARDATA
#if defined(__BORLANDC__)
    return(void*)_AFX_FP_OFF(lp);
#else
    ASSERT(_AFX_FP_SEG(lp) == _segname("_DATA"));
    return (void*)_AFX_FP_OFF(lp);
#endif
#else
    return lp;
#endif
}

Änderungen in AFX.H

Wie bereits erwähnt, können eine Reihe von Änderungen über die Datei AFX4BC.H abgewickelt werden. Damit die dort enthaltenen neuen Definitionen und Redefinitionen für alle Framework-Sourcen sichtbar sind, sollte diese Datei einfach in AFX.H per #include integriert werden:

MFC-Quellen

#ifndef __AFX_H__
#define __AFX_H__
 
#ifndef __cplusplus
#error Microsoft Foundation Classes require C++ compilation (use a .cpp suffix)
#endif
 
#if   defined(__BORLANDC__)
#include "afx4bc.h"
#endif
 
#include "afxver_.h"

Änderungen der übrigen Header-Dateien

Die restlichen Änderungen der Dateien AFXCOLL.H, AFXOLE.H, AFXPRIV.H, AFXDLGS.H, AFXEXT.H, AFXWIN.H, AFXPEN.H und AFX.H sind nicht unbedingt erforderlich, um die MFC mit BC++ zu verwenden. Allerdings erleichtern sie das Konfigurieren des Compilers und werden daher empfohlen.

Die genannten Headerdateien enthalten am Ende die nachfolgende Sequenz:

#undef AFXAPP_DATA
#define AFXAPP_DATA     NEAR

die gegen die folgende ausgetauscht werden sollte:

#if !defined(__BORLANDC__)
#undef AFXAPP_DATA
#define AFXAPP_DATA     NEAR
#endif

MFC 2.0 Library mit BC++ aufbauen

Der einfachste Weg zum Aufbau der MFC 2.0 besteht darin, ein Makefile zu verwenden. Die wichtigsten Makros sind:

Makro

Bedeutung

MFC_LIBNAME

Name der zu erzeugenden Bibliothek. Der Defaultname ist BCMFC_x, wobei x das Speichermodell bezeichnet. Bedingt durch die Größe der Bibliothek werden tatsächlich jedoch drei Libraries mit den Namen MFC_LIBNAME# erzeugt, wobei # für 1, 2 und 3 steht.

MODEL

Speichermodell; z. B. „l“ für Large oder „c“ für Compact. NEAR CODE Versionen der Bibliothek sind nicht möglich, da in der Regel ein Overflow im _TEXT Segment resultieren wird.

BCPATH

Basisverzeichnis von BC++; Default: C:\BORLANDC

MFCPATH

Basisverzeichnis der MFC; Default: C:\MSVC\MFC

Um beispielsweise das Speichermodell Large zu erzeugen, kann der folgende Aufruf verwendet werden, wobei angenommen wird, daß BC++ in D:\BC installiert und das Makefile nach MFC\SRC kopiert wurde:

MAKE -DBCPATH=D:\BC -f BCMFC.MAK

Die gezeigte Aufrufzeile plaziert die neu erzeugten Bibliotheken in das MFC\LIB-Verzeichnis und die OBJ-Dateien in ein neu angelegtes Verzeichnis mit dem Namen MFC\SRC\OBJS_x, wobei x der Buchstabe des Speichermodells ist.

Das komplette Makefile ist auf der CD in der Datei BCMFC.MAK enthalten und soll hier nicht noch einmal wiederholt werden.





Sachgebiet


© 2009-2012 by Alojado Publishing. Alle Rechte vorbehalten. Ausgewiesene Marken gehören ihren jeweiligen Eigentümern.
Mit der Benutzung dieser Seite erkennen Sie die Nutzungsbedingungen und die Datenschutzerklärung an. Der Betreiber übernimmt keine Haftung für den Inhalt verlinkter externer Internetseiten.
Seite erzeugt 2012-05-20 02:39:45 von textarchiv.alojado.de