How to link the msxml3.dll?

447 views
Skip to first unread message

ryan...@vodafone.net

unread,
Mar 12, 2007, 10:57:20 AM3/12/07
to
hi im wondering if anyone could be of great help! it really is
appreciated.

I have currently implemented the use of XML parsing functions within
VS2005 using the directive #import<msxml3.dll>, but im wanting to use
this in Borland Builder 6. My problem is i know that i cannot use
this #import directive to link to the DLL and use these XML
functions. After much research i used -Project | Create Type Library
form the menus bar, to try and create a static lib of the msxml3.dll,
the development environment told me that the TXMLDocument component
had already been implemented with the XML funtionality. After
several
days i could not find any information on how to use this component,
and i could not create an instance of the XMLDOM document. I really
didnt want to use the component either as i have already created my
XML specific classes. I thought i would still try though.


I have also used the TLIBIMP.exe to get a static lib of my DLL, which
has returned me a .cpp, a .h and a .TLB file. I also used the
TLIB.exe on the msxml3.dll and got a msxml3.lib, i have placed this
lib with all the other .lib files within the borland .lib directory,
and i have #include "msxml3_tlb.h" to my project. I can get the
intellisense of the msxml3.dll functions that i want to use, but i
get
an error saying that there is no reference to the funtion.


I really need to use this XML capability within my project, and i
would really appreciate if anyone could help me with this. I hope
this post is informative enough for you.


Many thanks Ryan.

Jean-Marie Babet

unread,
Mar 12, 2007, 1:40:35 PM3/12/07
to
Hello Ryan,

VC's #import is a way for C++ code to access a COM object. Behind the scene
the compiler imports the DLL (by reading the typelibrary embedded in the
DLL), generates some header files(*) and include them in your C++ source.
You are *not* linking in the MSXML DLL. IOW, you application still relies on
MSXML being present at runtime. You are using a binding to the objects
exposed by MSXML.

The equivalent is to use TLIBIMP to generate some bindings from MSXML and
include the headers generated by TLIBIMP in your source code.

NOTE: If you use the TXMLDocument component, that's exactly what the
component does behind the scene. It's a wrapper around MSXML. Unless you'd
rather not use any VCL component, TXMLDocument can be used as a wrapper to
MSXML.

Does that make sense? Please let me know if I can provide more information.

Cheers,

Bruneau.

PS: #import generates .tlh and .tli files from the typelibraries. You can
find these files in the build directory. Like the files generated by
TLIBIMP, they are simply bindings to types and interfaces declared in the
imported typelibrary. Unfortunately, TLIBIMP and #import don't use similar
naming conventions... so code that worked with #import bindings needs to be
adjusted/tweaked to work with TLIBIMP bindings... but the tweaks are minor
and once one see the pattern, it's easy to convert. They are things like
'Get/Put' vs. 'Get/Set'.


ryan...@vodafone.net

unread,
Mar 13, 2007, 2:08:52 PM3/13/07
to
Many thanks for your reply,

I understand now what you mean, so what i have done is i have used the
TLIBIMP.exe to produce a type library interface of the msxml3.dll,
this has returned only 4 files for me though, and through reading the
other posts i feel like i am missing 1. The produced by the TLIBIMP
are.

First the command i used:

tlibimp -c+ msxml3.dll

the files produced :

MSXML2_OCX.cpp
MSXML2_OCX.dcr
MSXML2_OCX.h
MSXML2_TLB.h

I have copied all 4 of these files to my project source directory and
i have #include "MSXML2_TLB.h"
then i have added MSXML2_OCX.cpp to the project files, but ive read
that i have to add a MSXML2_TLB.cpp to my project but i dont have this
file??? how do i aquire this file?

Ive made a quick console test to try and run what i currently have.

#include <windows.h>
#include "MSXML2_TLB.h"

using namespace Msxml2_tlb;

int main()
{
IXMLDOMDocumentPtr m_pObjDomDocument;
IXMLDOMProcessingInstructionPtr m_pXMLProcessingInstruction;

HRESULT hr;
hr = CoCreateInstance(::CLSID_DOMDocument, NULL,
CLSCTX_INPROC_SERVER, ::IID_IXMLDOMDocument,
(void **)&m_pObjDomDocument);

m_pXMLProcessingInstruction = m_pObjDomDocument-
>createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");


return 0;
}

my errors:
[C++ Error] XMLconsole.cpp(16): E2285 Could not find a match for
'Msxml2_tlb::IXMLDOMDocument::createProcessingInstruction(char *,char
*)'


Thankyou so much for your time!
Ryan

Remy Lebeau (TeamB)

unread,
Mar 13, 2007, 4:32:45 PM3/13/07
to

<ryan...@vodafone.net> wrote in message
news:1173809332.8...@c51g2000cwc.googlegroups.com...

> I have copied all 4 of these files to my project source directory
> and i have #include "MSXML2_TLB.h" then i have added
> MSXML2_OCX.cpp to the project files, but ive read that i have
> to add a MSXML2_TLB.cpp to my project but i dont have this
> file??? how do i aquire this file?

No. Everything is implemented inlined inside of the .h file directly.
In older versions of BCB, the only thing the .cpp ever held was the
definitions of GUIDs that were declared as 'extern' in the .h file.
The .cpp held nothing else. In newer versions, the GUIDs are inlined
as well, so the .cpp is redundant now.

> [C++ Error] XMLconsole.cpp(16): E2285 Could not find a match for
> 'Msxml2_tlb::IXMLDOMDocument::createProcessingInstruction(char
*,char
> *)'

That is because you are passing char* literals where BSTRs are
expected. Change this line:

m_pXMLProcessingInstruction =
m_pObjDomDocument->createProcessingInstruction("xml", "version='1.0'
encoding='UTF-8'");

To this instead:

m_pXMLProcessingInstruction =
m_pObjDomDocument->createProcessingInstruction(WideString("xml"),
WideString("version=\"1.0\" encoding=\"UTF-8\""));


Gambit


ryan...@vodafone.net

unread,
Mar 14, 2007, 5:38:32 AM3/14/07
to
Hi Gambit,

Many thanks for your swift reply! really appreciate it.
Thanks for the information above that has now worked, you was right
about all the GUIDs being inline int the MSXML3_TLB.h header file, It
just threw me looking around for .cpp after reading some other posts.
Once i had added the WideString( ) functions to my m_pObjDomDocument-
>createProcessingInstruction(), this then worked. My only problem
that then arose is that i had to upgrade to a newer version of the
UTILCLS.h file. My biggest problem here is that im unable to install
this as im using Borland builder 6 over my university network. This
is really frustrating, as ive produced a XML class for one of my
visual studio 2005 projects, and need this for my project that is
being created in borland, I wanted to use an XML class as i will have
many instances of open XML files, and also creating new ones possible
simultaneously, so i wasnt so keen on using a component. I think
that im going to have to use the TXMLDocument component and have
another look at how to get that working. I was a little confused at
how to create the the Preprocessing Instruction and the first node of
the tree using this component, or to create it without the component
just using the IXMLDocument? Would anyone be able to help.

Again thanks for the replies, i think your great.

Ryan

Remy Lebeau (TeamB)

unread,
Mar 14, 2007, 2:39:11 PM3/14/07
to

<ryan...@vodafone.net> wrote in message
news:1173865112.1...@l77g2000hsb.googlegroups.com...

> My only problem that then arose is that i had to upgrade to
> a newer version of the UTILCLS.h file.

Then you likely generated the TLB files using the wrong version of
TIMPLIB. Do you have multiple versions of BCB installed on your
machine?

> I think that im going to have to use the TXMLDocument
> component and have another look at how to get that working.
> I was a little confused at how to create the the Preprocessing
> Instruction and the first node of the tree using this component

You don't create the preprocessing instruction yourself. That is
generated automatically for you. TXMLDocument has Version and
Encoding properties that you can use to manipulate those values
individually as needed. As for creating the root node, simply call
TXMLDocument's CreateElement() method, and then assign the resulting
IXMLNode to the TXMLDocument's DocumentElement property.

> or to create it without the component just using the IXMLDocument?

Use the NewXMLDocument() function for that. Since TXMLDocument
derives from IXMLDocument, all of the tree building/processing
operations are identical after that.


Gambit


ryan...@vodafone.net

unread,
Mar 15, 2007, 1:29:23 PM3/15/07
to
Ps Gambit thanks for the help on creating IXMLDocument, im getting to
grips with this now.

Can anyone recognise this linker error and help? Many thanks

I am getting this linker error within my code and i know which line is
causing this error. What is frustrating is that i need to use the
funtionality of this function. What im wanting to be able to do is
use selectNode() funtion with and XPath statement.

This is my code

_di_IXMLDocument pXMLObjDocument;
_di_IDOMElement pIDOMElement;
_di_IDOMNodeSelect pIDOMNodeSelect;
_di_IDOMNode pSelectedNode;

pXMLObjDocument = NewXMLDocument();

if(pXMLObjDocument != NULL)
{
pXMLObjDocument->LoadFromFile(WideString(m_pFilePath));
pXMLObjDocument->Active = true;

pIDOMNodeSelect = (_di_IDOMNodeSelect)pXMLObjDocument-
>DOMDocument->documentElement; /*This line causes the problem,
because the linker msg goes when you comment this line out */

pIDOMNodeSelect-
>selectNode(WideString(pXmlQuery),pSelectedNode);
}

This is my linker error:
[Linker Error] Unresolved external 'System::__linkproc__ __fastcall
CheckAutoResult()' referenced from C:\PROGRAM FILES\BORLAND
\CBUILDER6\LIB\RELEASE\VCLE.LIB|syssupp

Many thanks hope you can help.
Ryan

This maybe because of my code.


ryan...@vodafone.net

unread,
Mar 15, 2007, 3:55:50 PM3/15/07
to
I fixed the linker error i had to add this to the top of the .CPP
file,

#include <comobj.hpp>

namespace System
{
void __fastcall CheckSafecallResult(HRESULT hr)
{
OleCheck(hr);
}
}


Im still struggling though to select a node through xpath and then
delete the selected node.

ryan...@vodafone.net

unread,
Mar 15, 2007, 4:06:51 PM3/15/07
to
I manage to use the XPath statement and i have manage to delete my
Node this is how i did it!!
{
_di_IXMLDocument pXMLObjDocument;
_di_IDOMElement pElement;
_di_IDOMNodeSelect SelectNode;
_di_IDOMNode Node;

pXMLObjDocument = NewXMLDocument();

if(pXMLObjDocument != NULL)
{
pXMLObjDocument->LoadFromFile(WideString(m_pFilePath));
pXMLObjDocument->Active = true;

SelectNode = (_di_IDOMNodeSelect)pXMLObjDocument-
>DOMDocument->documentElement;

if(SelectNode != NULL)
{
SelectNode->selectNode(WideString(pXmlQuery), Node);
pElement = pXMLObjDocument->DOMDocument-
>documentElement;

if(pElement != NULL)
{
pElement->removeChild(Node, NULL);
pXMLObjDocument->SaveToFile(WideString(m_pFilePath));
pXMLObjDocument->Release();
return true;
}
}
}
pXMLObjDocument->Release();
return false;
}


Ryan

Remy Lebeau (TeamB)

unread,
Mar 15, 2007, 7:11:10 PM3/15/07
to

<ryan...@vodafone.net> wrote in message
news:1173989211....@e65g2000hsc.googlegroups.com...

> pXMLObjDocument = NewXMLDocument();
>
> if(pXMLObjDocument != NULL)
> {
> pXMLObjDocument->LoadFromFile(WideString(m_pFilePath));

Use LoadXMLDocument() instead:

pXMLObjDocument = LoadXMLDocument(m_pFilePath);

> SelectNode = (_di_IDOMNodeSelect)pXMLObjDocument-
> >DOMDocument->documentElement;

You can get rid of cast:

SelectNode = pXMLObjDocument->DOMDocument->documentElement;

> pElement = pXMLObjDocument->DOMDocument-
> >documentElement;
>
> if(pElement != NULL)

You already know that the documentElement is valid since you were able
to get an IDOMNodeSelect from it by this point, so you don't need to
check it for NULL.

> pXMLObjDocument->Release();

Don't do that. The DelphiInterface class handles that for you
internally. By calling Release() manually, you are going to crash
your code when the DelphiInterface goes out of scope, because it is
going to call Release() again on an invalid pointer.

Try this instead:

{
_di_IXMLDocument Doc = LoadXMLDocument(m_pFilePath);
if( Doc )
{
_di_IDOMElement DocElement =
Doc->DOMDocument->documentElement;
if( DocElement )
{
_di_IDOMNodeSelect SelectNode = DocElement;
if( SelectNode )
{
_di_IDOMNode Node;
SelectNode->selectNode(pXmlQuery, Node);

if( Node )
{
DocElement->removeChild(Node, NULL);
Doc->SaveToFile(m_pFilePath);
return true;
}
}
}
}
return false;
}


Gambit


Reply all
Reply to author
Forward
0 new messages