Here's a MS official example of how to use MSXML
void AddCollectionSample()
{
IXMLDOMDocument2Ptr pIXMLDOMDocument2;
IXMLDOMSchemaCollection2Ptr pIXMLDOMSchemaCollection2Ptr;
...
}
The code is simple, but doesn't compile on my Visual Studio 2019 with the error can't find the declaration of IXMLDOMDocument2Ptr.
I've already included these headers and lib.
#include "msxml2.h"
#include "msxml6.h"
#pragma comment(lib, "msxml6.lib")
I searched this IXMLDOMDocument2Ptr online and found out it's supposed to be under MSXML2 (a namespace). But my project doesn't recognize this namespace as well. Then I found it, you have to import this library,#import <msxml6.dll>
But this is supposed to be for C#. How about my C++ project?
Edit:
I find this,
https://www.codeproject.com/Articles/43309/How-to-create-a-simple-XML-file-using-MSXML-in-C
The first thing you need to do is add these two lines in the project stdafx.h file:
#import "MSXML4.dll" rename_namespace(_T("MSXML"))
#include <msxml2.h>
I modified this MSXML4.dll to my newly MSXML6.dll, but the project can't find it still.
The sample code is using _com_ptr_t, a COM smart pointer class template provided by Visual Studio. Yet the code provided is incomplete.
To declare a _com_ptr_t specialization for any given interface you would usually use the _COM_SMARTPTR_TYPEDEF macro. In this case the following declarations need to be added:
_COM_SMARTPTR_TYPEDEF(IXMLDOMDocument2, __uuidof(IXMLDOMDocument2));
_COM_SMARTPTR_TYPEDEF(IXMLDOMSchemaCollection2, __uuidof(IXMLDOMSchemaCollection2));
This declares the types IXMLDOMDocument2Ptr and IXMLDOMSchemaCollection2Ptr as specializations of _com_ptr_t, ready to be used. You'll need to #include <comip.h>, too.
An alternative would be to use the compiler specific #import directive. This generates header files from a type library (TLB), and by default includes the respective _COM_SMARTPTR_TYPEDEF declarations (see Primary type library header file).
From this demo
The first thing you need to do is add these two lines in the project stdafx.h file:
#import "MSXML6.dll" rename_namespace(_T("MSXML"))
#include <msxml2.h>
Then correct all the MSXML2 to MSXML, as we specified the name rename_namespace(_T("MSXML")).
I didn't bother to do this, I at first tried namespace MSXML2=MSXML didn't work. So I just defined a MACRO #define MSXML2 MSXML. It compiled!
Related
I want to make use of the module support for consuming the C++ std library in Visual Studio/C++ 2017. I have code which makes use of the assert macro but I can't seem to get the definition of assert from the std library modules. For example:
import std.core;
void f()
{
assert(true);
}
Fails with errors:
1>API_Constants.cpp(10): error C3861: 'assert': identifier not found
What do I need to do to get the definition of assert?
Update 1
Thanks to those who suggested #include <cassert> that was what I have been trying. Unfortunately, for the code:
import std.core;
#include <cassert>
import std.core;
I get the following errors:
1>verify-header-compilation.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.12.25827\include\vadefs.h(134): error C2953: '__vcrt_va_list_is_reference': class template has already been defined
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.12.25827\include\vadefs.h(131): note: see declaration of '__vcrt_va_list_is_reference'
Note that the following works so I will need to put the #include <cassert> as the first include of any cpp file that uses assert (similar to the way pre-compiled header includes need to be the first include).
#include <cassert>
import std.core;
import std.core;
Update 2
While appropriately placed #include <cassert> resolves my specific question I have hit the same problem with other macros from standard headers. In particular I am now in trouble with RAND_MAX from cstdlib and pulling the same trick does not work. It would seem that these headers need to be rewritten so that it is possible to mix includes with imports or we need new headers that just give us the macros.
Update 3
Note that making #include <cassert> the last include in a cpp file is problematic for two reasons. First, I use assert with templates in headers so I would need to edit a non-trivial amount of files to get this to work. Second, the following doesn't compile at present (fails with same errors as above):
import std.core;
#include <cassert>
Maybe you need #include <cassert> at the top of your file.
The MSVC doc about cpp modules says:
Standard Library Modules (Experimental)
std.regex provides the content of header <regex>
std.filesystem provides the content of header <experimental/filesystem>
std.memory provides the content of header <memory>
std.threading provodes the contents of headers <atomic>, <condition_variable>, <future>, <mutex>, <shared_mutex>, <thread>
std.core provides everything else in the C++ Standard Library
So it should be included. But maybe StoryTeller is right and macros are not included.
You need to move #include to be the final header file included, so that the assert macro is not undefined, i.e., so that the assert macro applies to this .cpp file's source code.
//........Project for ABC.dll
//ABC.h
#pragma once
class ABC{
public:
ABC(){}
private:
std::vector<int> m_vector;
};
//ABC.cpp
#include "Stdafx.h"
#include "ABC.h"
//Stdafx.h
#include <vector>
Till today, I've skipped #include <standard-lib.h> in my headers by delegating it to Stdafx.h header.
It's never been a problem when I worked in a single project file.
Now I'm trying to add a new DLL project to gather shared codes in one project.
It compiled well and generated ABC.dll too.
Here's a problem. When another project that uses ABC.dll show compile error saying that std::vector does not exist.
//...........Another Project using ABC.dll
int main(){
ABC abc;
}
Error C2039 'vector': is not a member of 'std'
To get it working, I had to include all the libraries in the consumer's Stdafx.h too.
Maybe I've been misusing the precompiled header.
I want to know whether the way I've been doing with the PCH was wrong or right.
If it's wrong, I would appreciate it if you suggest right ways of using PCH.
Thanks.
Your problems have nothing to do with precompiled headers. A good practice is to include all the stuff directly used by current file. This will prevent changes in includes of one header file from potentially requiring changes in includes in files that are using this header. vector needs to be included in ABC.h because it is directly used there. Otherwise you'll end up with endless struggling to figure out which headers needs to be included when including this particular library header.
I have set up a project in Visual Studio to create a .dll. I have included an external library in the project which uses the keyword "interface". This is giving me the following error:
error C2146: syntax error : missing ';' before identifier 'INuiAudioBeam'
These are the lines of code where the error occurs:
#ifndef __INuiAudioBeam_FWD_DEFINED__
#define __INuiAudioBeam_FWD_DEFINED__
typedef interface INuiAudioBeam INuiAudioBeam; //Error on this line
#endif
The above code is part of a header file in the external library I have included. The project builds successfully without any errors when compiling without including the headers for the library (Note: Linking the library does not cause any problems).
What is the solution to this? Is it because I have an external library I'm using to create my dll? Should I create a .lib instead of a dll?
If anyone else searches this, the problem is most likely
#define WIN32_LEAN_AND_MEAN
Before
#include <windows.h>
Remove the define, make sure your including windows.h, and that should define interface keyword for you
You can get C2146 with indictment of the interface keyword. It may be confusing as to how a keyword may be undefined, especially that in other compilation units or projects that use the same header file - the inclusion of which brought about the problem - all goes smooth. However, the apparent keyword "interface" is still a compiler #define directive. It just happens to be buried inside a header file that a few developers have reasons to inspect: the <objbase.h>. There it is defined in two steps:
#define __STRUCT__ struct
#define interface __STRUCT__
Since the <objbase.h> is included by multiple other header files - such as ole2.h, oleauto.h, and a slew of ATL headers - you may be surprised with this error when none of those headers were included in the current compilation unit.
I'm trying to include secExt.h in my C++ project and it gives me the error:
error C2086: 'BOOLEAN SEC_ENTRY' : redefinition
How can I fix it?
EDIT: from microsoft's docs, include security.h, not [secext.h].
original answer (before I googled the header name myself, no info given by OP):
if the header is yours, add
#pragma once
at the top.
if that doesn't work (there is reportedly a compiler on some IBM system or something that doesn't support #pragma once), then use a header guard.
if the header isn't yours, create a header wrapper like this:
#pragma once
#include <secExt.h>
then include your wrapper header instead of including [secExt.h] directly.
I wish to use a COM dll in my C++ library.
The way I figured going about it, is to #import the dll's .tlb file, which I did :
#import "mycom.tlb" no_namespace
The problem is , I don't quite know where to place this declaration. should it be inside the H file or the CPP file? or maybe the stdafx.h file?
I tried placing it in the .cpp file , just for testing.
in the H file I have this member declared :
ILogicSecuredPtr m_pbLogic;
(where ILogicSecured is the interface I want to work with in my COM dll)
Then I added this in the constructor to instantiate the interface :
CoInitialize(NULL);
m_pbLogic(__uuidof(LogicSecured));
(where LogicSecured is the name of the object that implements the interface)
In the destructor I added :
CoUninitialize();
This won't compile however, no matter where I try to place the #import declaration.
it just doesn't recognize the ILogicSecured object.
I get this error in the H file :
Error 2 error C2146: syntax error : missing ';' before identifier 'm_pbLogic'
I should also mention that when I F12 (in Visual Studio) on the ILogicSecuredPtr declaration, it takes me to the tlh file just fine. So I know it recognizes it.
What am I doing wrong here?
Thanks alot.
Roey
The problem is that when the compiler parses the .h file it has not seen the #import yet. Since your project is small your best bet is to put #import into stdafx.h.
When you press F12 Visual Studio uses Intellisence database information that is formed parsing all the sources in order that might be different from the compilation order. So it's quite typical to have Intellisence know where something is declared and the compiler to not compile it at the same time.
What happens if you import a dll or tlb file is that the preprocessor generates a tlh and a tli file.
If the tlb is stable you could also generate the two files and include the tlh header as if its a normal header.
So the answer is put the #import where you would put the header because it is converted into an include of the tlh file.
I use it in the following way to make myself independent of the location of the MSADO15.dll and added the tlh file to my subversion.
#ifndef __ADO__H
#define __ADO__H
#ifdef REBUILD_ADO_HEADER
#import "C:\Programme\Gemeinsame Dateien\system\ado\MSADO15.DLL" rename_namespace("MyAdoNamespace") rename("EOF","EndOfFile")
#else // REBUILD_ADO_HEADER
#include "MSADO15.tlh"
#endif // REBUILD_ADO_HEADER
// Define ADO Namespace as global
using namespace MyAdoNamespace;
#endif // __ADO__H
In addition to the compile issues you are having, there are other problems with this design.
Generally, C++ libraries should not initialize COM on threads that it does not create. This can cause some nasty, hard to debug side effects. Consider updating the interface spec for your library to indicate that use of certain methods or objects require that COM be initialized. You should also specify the threading model required (STA, Free).
That said - the other thing you need to watch out for is calling CoUnitialize() before your smart pointer goes out of scope. This can also cause some hard to debug side-effects. If you're calling CoUnitialize() in the destructor of an object that contains a COM smart pointer, you'll need to explicitly release and detach the pointer prior to invoking CoUnitialize().
Have fun!