Discussion:
c++builder 6.0 and COM
(too old to reply)
Aidal
2006-10-24 07:24:53 UTC
Permalink
Hi NG.

I've asked about this earlier in another NG and was directed here, so I
hope this is the right place this time around.

My question is pretty simple.

I'm a C# developer myself so I'm not very familiar with native C++ and
the terms of borland c++builder.

I'm engaged in a small project that requires the development of a c++
DLL that uses a COM component.

I know how to find info on how to work with COM from .NET (Interop) but
I haven't had much luck finding the same info for c++builder, probably
because I'm not using the "right" terms in my search.

Aka I'm not interested in knowing how to build COM components with
c++builder but how to use/include/import a COM components from/into a
c++builder DLL project.

Any help, examples, links to info about this would be much appreciated,
thanks.

/Aidal
Aidal
2006-10-24 08:03:09 UTC
Permalink
Post by Aidal
Hi NG.
I've asked about this earlier in another NG and was directed here, so I
hope this is the right place this time around.
My question is pretty simple.
I'm a C# developer myself so I'm not very familiar with native C++ and
the terms of borland c++builder.
I'm engaged in a small project that requires the development of a c++
DLL that uses a COM component.
I know how to find info on how to work with COM from .NET (Interop) but
I haven't had much luck finding the same info for c++builder, probably
because I'm not using the "right" terms in my search.
Aka I'm not interested in knowing how to build COM components with
c++builder but how to use/include/import a COM components from/into a
c++builder DLL project.
Any help, examples, links to info about this would be much appreciated,
thanks.
/Aidal
Ok, I finally found somthing under project -> import type library, and I
found my COM component in the list.
However, "Pallete Page" ??? I picked COM+ since it's not ActiveX and I
don't really know the rest.

So I now got:
-------------
MyInterop_OCX.cpp
MyInterop_OCX.dcr
MyInterop_OCX.h
MyInterop_TLB.cpp
MyInterop_TLB.h

Which is how it's supposed to be I guess... Now where do I go from here
to start using the COM component from my project and how to go about this?

/Aidal
Remy Lebeau (TeamB)
2006-10-24 17:13:59 UTC
Permalink
Post by Aidal
However, "Pallete Page" ???
It is asking you to pick the Component Palette tab that you want to install
the ActiveX control under, if you choose to have the wizard generate a VCL
wrapper component for you.
Post by Aidal
Now where do I go from here to start using the COM component
from my project and how to go about this?
If you generated a wrapper component, then simply drop it onto your Form
like any other component.

If you did not generate a wrapper component, then add the generated .cpp
files to your project, #include the .h files into your code, and then use
the declared interfaces in your code as needed. There should be wrapper
class in there that will help you instantiate your control's object at
runtime.


Gambit
Aidal
2006-10-31 09:15:25 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Aidal
However, "Pallete Page" ???
It is asking you to pick the Component Palette tab that you want to install
the ActiveX control under, if you choose to have the wizard generate a VCL
wrapper component for you.
Post by Aidal
Now where do I go from here to start using the COM component
from my project and how to go about this?
If you generated a wrapper component, then simply drop it onto your Form
like any other component.
If you did not generate a wrapper component, then add the generated .cpp
files to your project, #include the .h files into your code, and then use
the declared interfaces in your code as needed. There should be wrapper
class in there that will help you instantiate your control's object at
runtime.
Gambit
Ok, this isn't a Form project so there are no forms to drag stuff on to,
it's a DLL project.
I tried to add "MyInterop_OCX.cpp" and "MyInterop_TLB.cpp" to the
project and include the header files (#inclide <MyInterop_OCX.h> and
#include <MyInterop_TLB.h>).

When I try to build the project I get loads of errors in completly new
files like: sysmac.H, System.hpp, dstring.h, systobj.h which I have not
altered in any way.

I'm not expecting anyone to sit and debug my code but I'm guessing
somone with the proper knowledge about this language/compiler could
maybe see what's wrong here as I'm guessing it must be somthing general.
The only thing I've done since the very very simple DLL project compiled
with no errors, is to add the 2 .cpp files to the project and to include
the 2 .h files into my Unit1.c which is the main code file of the project.

I'm not gonna post every error but some of them at least:
The very first one is:
[C++ Error] sysmac.H(50): E2040 Declaration terminated incorrectly.
It point to the first line of the following code, which I didn't write.

------------------------------------
extern "C" {
#pragma option push -vi

#undef GetDiskFreeSpaceEx
inline BOOL WINAPI GetDiskFreeSpaceEx(LPCTSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes)
{
return _MAP_WINNAME(GetDiskFreeSpaceEx)(lpDirectoryName,
lpFreeBytesAvailableToCaller,
lpTotalNumberOfBytes,
lpTotalNumberOfFreeBytes);
}

#pragma option pop // -vi
} // extern "C"
------------------------------------

The second error is: [C++ Error] sysmac.H(150): E2141 Declaration syntax
error. It points to the first line of the following code which I didn't
write.

------------------------------------
namespace System
{

// Forward ref. for QI of IInterface
template <class T> class RTL_DELPHIRETURN DelphiInterface;

// NOTE: IInvokable is really IUnknown - with the same UUID - resolves
the mangling issues
// we've been having in COM stuff
__interface INTERFACE_UUID("00000000-0000-0000-C000-000000000046")
IInterface : public IUnknown
{
public:
/** Template function to ease querying for a smart-Interface-object */
template <typename T>
bool __stdcall Supports(DelphiInterface<T>& smartIntf)
{
return QueryInterface(__uuidof(T),
reinterpret_cast<void**>(static_cast<T**>(&smartIntf))) == S_OK;
}
};

// Base type from which SOAP remotable interfaces derive.
// It triggers the compiler to generate RTTI for the
// methods and their parameters. This information is then
// used to expose the interface as SOAP ports/operations.
//
// NOTE: IInvokable is really IInterface - with the same UUID - with
__declspec(delphirtti)
__interface INTERFACE_UUID("00000000-0000-0000-C000-000000000046")
DECLSPEC_DRTTI IInvokable : public IInterface
{};

class DELPHICLASS TObject;
class PACKAGE TMetaClass;
typedef TMetaClass* TClass;
template <class T> class RTL_DELPHIRETURN DelphiInterface;
class DELPHICLASS TInterfacedObject;

class RTL_DELPHIRETURN AnsiString;
class RTL_DELPHIRETURN WideString;

template <unsigned char sz> class SmallStringBase;
template <unsigned char sz> class SmallString;

class RTL_DELPHIRETURN CurrencyBase;
class RTL_DELPHIRETURN Currency;

class RTL_DELPHIRETURN OleVariant;
class RTL_DELPHIRETURN Variant;

struct PACKAGE TLibModule;
struct PACKAGE TModuleUnloadRec;

class PACKAGE THeapStatus;
class PACKAGE TMemoryManager;

class PACKAGE TVariantManager;
/* class PACKAGE TDynArrayTypeInfo; */

// Inspector Query
struct THeapBlock;

template<class T> class RTL_DELPHIRETURN DynamicArray;

typedef DynamicArray<THeapBlock> THeapBlockArray;
typedef DynamicArray<System::TObject *> TObjectArray;

// Inspector Query

typedef class TMemoryManager *PMemoryManager;
typedef class TVariantManager *PVariantManager;

class RTL_DELPHIRETURN TDateTimeBase;
class RTL_DELPHIRETURN TDateTime;

struct CompBase;
struct Comp;

struct PACKAGE TLibModule;
typedef TLibModule *PLibModule;

struct PACKAGE TResStringRec;
typedef TResStringRec *PResStringRec;

template<class T, unsigned char minEl, unsigned char maxEl> class
RTL_DELPHIRETURN SetBase;
template<class T, unsigned char minEl, unsigned char maxEl> class
RTL_DELPHIRETURN Set;

class PACKAGE TVarArrayBound;
class PACKAGE TVarArray;
typedef TVarArray *PVarArray;
typedef int TVarArrayCoorArray;
typedef TVarArrayCoorArray *PVarArrayCoorArray;


typedef bool Boolean; //
typedef int Integer; //
-2147483648..2147484647
typedef char Char; // 0..255
typedef wchar_t WideChar; // Unicode character
typedef signed char Shortint; // -128..127
typedef short Smallint; // -32768..32767
typedef unsigned char Byte; // 0..255
typedef unsigned short Word; // 0..65535
typedef unsigned long DWord; // 0..4294967295
typedef unsigned LongWord; // 0..4294967295
typedef void* Pointer; //
typedef char AnsiChar; //
typedef signed long Longint; //
-2147483648..2147484647
typedef unsigned int Cardinal; // 0..4294967295
typedef long double Extended; // 10 byte real
typedef float Single; // 4 byte real
typedef double Double; // 8 byte real
typedef char* const Openstring; // D16 string/D32
shortstring formalparm
typedef void* file; //
typedef void* Text; //
typedef Text TextFile; //
typedef char* PChar; //
typedef char* PAnsiChar; //
typedef wchar_t* PWideChar; //
typedef unsigned char ByteBool; //
typedef unsigned short WordBool; //
typedef Cardinal LongBool; //
typedef AnsiString String; //
typedef SmallStringBase<255> ShortStringBase; //
typedef SmallString<255> ShortString; //
typedef ShortString* PShortString; //
typedef AnsiString* PAnsiString; //
typedef PAnsiString PString; //
typedef WideString* PWideString; //
typedef Extended* PExtended; //
typedef Currency* PCurrency; //
typedef Variant* PVariant; //
typedef OleVariant* POleVariant; //
typedef GUID TGUID; //
typedef TGUID* PGUID; //
typedef HRESULT HResult; //
typedef AnsiString UTF8String;
typedef PAnsiString PUTF8String;

typedef Byte* PByte; //
typedef Integer* PInteger; //
typedef LongWord* PLongWord; //
typedef int* PLongint; //
typedef short* PShortint; //
typedef short* PSmallInt; //
typedef bool* PBoolean; //
typedef PChar* PPChar; //
typedef double* PDouble; //
typedef LongWord UCS4Char; //
typedef LongWord* PUCS4Char; //
typedef DynamicArray<UCS4Char> UCS4String; //

typedef Integer __fastcall (*TThreadFunc)(Pointer Parameter);
typedef void (*TModuleUnloadProc)(HINSTANCE hinstance);
typedef bool (*TEnumModuleFunc)(HINSTANCE hinstance, void *data);
typedef void (*TModuleUnloadProcLW)(HINSTANCE hinstance);
typedef bool (*TEnumModuleFuncLW)(HINSTANCE hinstance, void *data);
typedef void (*TAssertErrorProc) (const AnsiString Message,
const AnsiString Filename,
int LineNumber,
void *ErrorAddr);
typedef void (*TSafeCallErrorProc) (HRESULT ErrorCode, void
*ErrorAddr);
typedef void (*TDLLProc) (int Reason);
typedef void (*TDLLProcEx) (int Reason, int Reserved);

typedef struct TVarData *PVarData;
enum TTextLineBreakStyle { tlbsLF, tlbsCRLF };

struct TMethod
{
void *Code;
void *Data;
};

typedef System::DelphiInterface<System::IInterface> _di_IInterface;
}
------------------------------------

Then there are a few more systax errors about the "namespace System" and
"namespace Sysutils" and then it has some errors in the same area og
systobj.h.
[C++ Error] systobj.h (417): E2257 , expected.
In the first line of the following code:

------------------------------------
DECLARE_DINTERFACE_TYPE(IUnknown)
DECLARE_DINTERFACE_TYPE(IDispatch)
DECLARE_DINTERFACE_TYPE(IAdviseSink)
DECLARE_DINTERFACE_TYPE(IDataAdviseHolder)
...
...
...
------------------------------------

After the above error there are a lot of
[C++ Error] systoj.h (418 through 435) E2040 Declaration terminated
incorrectly. Again in code I didn't write.

------------------------------------
DECLARE_DINTERFACE_TYPE(IUnknown)
DECLARE_DINTERFACE_TYPE(IDispatch)
DECLARE_DINTERFACE_TYPE(IAdviseSink)
DECLARE_DINTERFACE_TYPE(IDataAdviseHolder)
DECLARE_DINTERFACE_TYPE(IDataObject)
DECLARE_DINTERFACE_TYPE(IEnumOLEVERB)
DECLARE_DINTERFACE_TYPE(IEnumFORMATETC)
DECLARE_DINTERFACE_TYPE(IEnumSTATDATA)
DECLARE_DINTERFACE_TYPE(ILockBytes)
DECLARE_DINTERFACE_TYPE(IMalloc)
DECLARE_DINTERFACE_TYPE(IMoniker)
DECLARE_DINTERFACE_TYPE(IOleAdviseHolder)
DECLARE_DINTERFACE_TYPE(IOleClientSite)
DECLARE_DINTERFACE_TYPE(IOleContainer)
DECLARE_DINTERFACE_TYPE(IOleInPlaceActiveObject)
DECLARE_DINTERFACE_TYPE(IOleInPlaceFrame)
DECLARE_DINTERFACE_TYPE(IOleInPlaceObject)
DECLARE_DINTERFACE_TYPE(IOleInPlaceSite)
DECLARE_DINTERFACE_TYPE(IOleInPlaceUIWindow)
DECLARE_DINTERFACE_TYPE(IOleObject)
DECLARE_DINTERFACE_TYPE(IStorage)
DECLARE_DINTERFACE_TYPE(IStream)
DECLARE_DINTERFACE_TYPE(ITypeInfo)
DECLARE_DINTERFACE_TYPE(ICreateTypeInfo)
DECLARE_DINTERFACE_TYPE(ITypeLib)
DECLARE_DINTERFACE_TYPE(ICreateTypeLib)
DECLARE_DINTERFACE_TYPE(IConnectionPointContainer)
DECLARE_DINTERFACE_TYPE(IConnectionPoint)
DECLARE_DINTERFACE_TYPE(IEnumConnectionPoints)
DECLARE_DINTERFACE_TYPE(ISimpleFrameSite)
DECLARE_DINTERFACE_TYPE(IPropertyBag)
DECLARE_DINTERFACE_TYPE(IEnumConnections)
DECLARE_DINTERFACE_TYPE(IOleControl)
DECLARE_DINTERFACE_TYPE(IOleControlSite)
DECLARE_DINTERFACE_TYPE(IPerPropertyBrowsing)
DECLARE_DINTERFACE_TYPE(IFontDisp)
DECLARE_DINTERFACE_TYPE(IPersistStreamInit)
DECLARE_DINTERFACE_TYPE(IPicture)
DECLARE_DINTERFACE_TYPE(IPictureDisp)
DECLARE_DINTERFACE_TYPE(IPropertyPageSite)
DECLARE_DINTERFACE_TYPE(IOleClientSite)
DECLARE_DINTERFACE_TYPE(IErrorLog)
DECLARE_DINTERFACE_TYPE(IEnumOLEVERB)
DECLARE_DINTERFACE_TYPE(IOleDocumentView)
DECLARE_DINTERFACE_TYPE(IOleAdviseHolder)
DECLARE_DINTERFACE_TYPE(IOleContainer)
DECLARE_DINTERFACE_TYPE(IOleInPlaceActiveObject)
DECLARE_DINTERFACE_TYPE(IOleInPlaceObject)
DECLARE_DINTERFACE_TYPE(IOleInPlaceUIWindow)
DECLARE_DINTERFACE_TYPE(IOleInPlaceFrame)
DECLARE_DINTERFACE_TYPE(IOleObject)
DECLARE_DINTERFACE_TYPE(IOleInPlaceSite)
DECLARE_DINTERFACE_TYPE(IOleInPlaceObjectWindowless)
------------------------------------

Any help would be much appreciated, as I have little knowledge in this
area. Problem is I'm forced to work with it...

/Aidal
Remy Lebeau (TeamB)
2006-10-31 17:25:23 UTC
Permalink
Post by Aidal
Ok, this isn't a Form project so there are no forms to drag stuff
on to, it's a DLL project.
Then you will have to use the TCoClassCreator wrapper class that is declared
in the TLB.h file, or use the API CoCreateInstance() function directly
instead.
Post by Aidal
When I try to build the project I get loads of errors in completly new
files like: sysmac.H, System.hpp, dstring.h, systobj.h which I have not
altered in any way.
Those are all VCL headers. Did you enable the VCL when you created the DLL
project? If not, then you need to re-create the DLL project and enable the
VCL option.
Post by Aidal
[C++ Error] sysmac.H(50): E2040 Declaration terminated incorrectly.
It point to the first line of the following code, which I didn't write.
There is nothing wrong with that code. The declaration is accurate.
Post by Aidal
The second error is: [C++ Error] sysmac.H(150): E2141 Declaration syntax
error. It points to the first line of the following code which I didn't
write.
Again, there is nothing wrong with that code.
Post by Aidal
[C++ Error] systobj.h (417): E2257 , expected.
And again.
Post by Aidal
[C++ Error] systoj.h (418 through 435) E2040 Declaration terminated
incorrectly. Again in code I didn't write.
And again.


Gambit
Aidal
2006-11-01 11:39:56 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Aidal
Ok, this isn't a Form project so there are no forms to drag stuff
on to, it's a DLL project.
Then you will have to use the TCoClassCreator wrapper class that is declared
in the TLB.h file, or use the API CoCreateInstance() function directly
instead.
Post by Aidal
When I try to build the project I get loads of errors in completly new
files like: sysmac.H, System.hpp, dstring.h, systobj.h which I have not
altered in any way.
Those are all VCL headers. Did you enable the VCL when you created the DLL
project? If not, then you need to re-create the DLL project and enable the
VCL option.
Post by Aidal
[C++ Error] sysmac.H(50): E2040 Declaration terminated incorrectly.
It point to the first line of the following code, which I didn't write.
There is nothing wrong with that code. The declaration is accurate.
Post by Aidal
The second error is: [C++ Error] sysmac.H(150): E2141 Declaration syntax
error. It points to the first line of the following code which I didn't
write.
Again, there is nothing wrong with that code.
Post by Aidal
[C++ Error] systobj.h (417): E2257 , expected.
And again.
Post by Aidal
[C++ Error] systoj.h (418 through 435) E2040 Declaration terminated
incorrectly. Again in code I didn't write.
And again.
Gambit
I'm very greatful for your replies Remy, it's very helpful :)

I will try to re-create the project and make sure to enable VCL.

Also studying MyInterop_OCX.h a little closer I found this phrase:

------------------------------------------------------------------
#if !defined(__UTILCLS_H_VERSION) || (__UTILCLS_H_VERSION < 0x0600)
//
// The code generated by the TLIBIMP utility or the Import|TypeLibrary
// and Import|ActiveX feature of C++Builder rely on specific versions of
// the header file UTILCLS.H found in the INCLUDE\VCL directory. If an
// older version of the file is detected, you probably need an update/patch.
//
#error "This file requires a newer version of the header UTILCLS.H" \
"You need to apply an update/patch to your copy of C++Builder"
#endif
-------------------------------------------------------------------

Does this mean that what I'm trying to do will not work untill I patch
my C++Builder ?

/Aidal
Remy Lebeau (TeamB)
2006-11-01 21:26:52 UTC
Permalink
Unless you are actually seeing that error message appear in the compiler's
output, then ignore it.


Gambit
Aidal
2006-11-03 07:50:10 UTC
Permalink
Post by Remy Lebeau (TeamB)
Unless you are actually seeing that error message appear in the compiler's
output, then ignore it.
Gambit
Ok, I found out somthing else that is rather embarassing. I have a tiny
bit of sample code to show me how functions and dll entry point should
look, in order to make some specific semi ancient application able to
use it.

I found that for my entry point (the part auto generated when starting a
dll projet) to look like the one in the same code, I've aparently had to
make it a C project (where you can choose from C and C++) and not C++.

I found out because my Unit1 file has ".c" extension when I was trying
to recreate the project, like you said.
This seems to be a problem because I cannot seem to enable VCL for the
project, when I pick C instead of C++.

Continue reading on narkive:
Loading...