I'm trying to compile a VC++ project I've inherited that uses MSXML2. This is an ATL .EXE project. A header file includes the following:
#include "msxml2.h"
using namespace MSXML2;
Preprocessor definitions include __USE_MSXML2_NAMESPACE__, which I added to the project because without it the MSXML2 namespace was undefined. Attempting to build this project I receive many errors of the form:
error C2039: 'IXMLDOMNode' : is not a member of 'MSXML2'
These errors are produced by declarations like the following
CComPtr<MSXML2::IXMLDOMNode> pNode;
Other members are not found, including IXMLDOMDocument and IXMLDOMNode.
You can fix this
Include msxml2.h header.
Remove USE_MSXML2_NAMESPACE and using namespace MSXML2 code.
Use CComPtr<IXMLDOMNode> pNode; without namespace.
I've seen many projects using import keyword to ask Visual C++ to generate the header file from TBL using MSXML2 namespace. However, using header and linking to lib is my favorite way to avoid using import keyword as it is not c++ standard. The bottom line is to avoid mixing the two approaches when refreshing old projects, which will lead to problems like this.
Related
I have built Xerces-c_3_1.dll from source using the Visual Studio solution provided in the download package. It works with the sample applications that are part of that package (as long as they're built with VS).
But I need to use the DLL with apps developed in C++ Builder 10 Seattle. The incompatible linkage and COFF-vs-OMF format issues (import lib) mean I need to tweak the build instructions. I believe I need to change the calling convention in the project properties from __cdecl to __stdcall, and add a DEF file to translate the exported functions for my environment.
(I believe this because I wrote and support a DLL that is used by programmers writing in many languages. I do my development in C++ Builder [familiarity with the environment], and create the release version in VS Express 2015 [massive performance improvement over Embarcadero, I'm sorry to say]. Added a DEF file for just the 32-bit version [not needed for VC++ 64-bit, just to make me nuts], and it works for everybody.)
Running TDUMP.exe on my DLL gets me output that looks like this:
EXPORT ord:0060='Edit_RunEdits'
Running tdump -ee xerces-c_3_1.dll >tdump.txt on the Xerces-c_3_1.dll built using __cdecl gets output like this:
EXPORT ord:1763='?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z'
EXPORT ord:1764='?Initialize#XMLPlatformUtils#xercesc_3_1##SAXQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z'
Running impdef def.txt xerces-c_3_1.dll on the __cdecl build gets output like this:
?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z #1763; ?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z
Repeating TDUMP and IMPDEF on the __stdcall build gets similar results.
And this is expected.
But how can I create a DEF file from this noise? I would be perfectly happy with a sample of the format to use to turn "Initialize#XMLPlatformUtils" into something the linker can match to "XMLPlatformUtils::Initialize()" in my client app.
By the way, I also used IMPLIB on both versions (__cdecl and __stdcall) to create an import library, which I added to my test project, but the linker continues to issue "unresolved external" errors for my calls to XMLPlatformUtils::Initialize and XMLPlatformUtils::Terminate. I believe that should be expected because of the name mangling.
I have downloaded an API to further develop it and this error appears: C2065 CShellManager not declared. I guess it might be declared in a library which is not included by default, but it should be in the zip I have downloaded. How can a look for the declaration of this class in order to know the file in which is declared and to include this library in the source code?
The CShellManager class is a part of MFC framework. It is defined in afxshellmanager.h header file.
This class was introduced in VS 2008 as part of so called MFC Feature Pack.
Basically it is only required if your project uses CMFCShellTreeCtrl and such. If this is the case then you need to call CWinAppEx::InitShellManager() in OnInitInstance() of your app class to initialize the instance of the Shell Manager.
I am currently working on a Node.JS project written in TypeScript using Node.JS Tools for Visual Studio (NTVS). I have a few classes and enums spread out in 3 or 4 files in my project. I am now trying to use the classes defined in those files from my main app file. From my previous work with Node, I know that I would normally need a require call to import each other file/class if I were working with a text editor and the command-line compiler. But, if I open any TypeScript file in my project and start typing the name of a class defined in a different file, Visual Studio shows IntelliSense autocomplete for the class name and its members. This makes me think that the NTVS and/or TypeScript configuration are automatically making all of my classes available project-wide. But if I click the 'run' button, errors are printed to the console because Node can't find the referenced classes at runtime.
This behavior leads me to believe that IntelliSense isn't actually telling me that the classes are available, just that they exist (which seems odd). If I add a require call to the top of the file, and use that imported value instead of the original class name, Node finds the class and I can use it in my code. But this presents two problems:
I must come up with a new name to use for the variable that I import the class into. If I require() it with the original name, Visual Studio shows errors saying that the identifier is a duplicate, because it seems to believe that the original class is available project-wide.
I don't get the autocomplete or type checking in my usage of the class. This pretty much defeats the purpose of using TypeScript.
So, what's the proper way to do this import? Is there a way to make all my classes available globally? If not, what import statements do I need?
This behavior leads me to believe that IntelliSense isn't actually telling me that the classes are available, just that they exist
unless you have top level import or export statement the file is considered a global module and is available project wide : http://basarat.gitbooks.io/typescript/content/docs/project/modules.html
A global module will not work at runtime in node.js
You should use file level modules using import/export and compile with --module commonjs
I have a tlb files that contains some function declaration that I need to use.
If I use
#import "type_library.tlb"
I can correclty reference the function from my code:
tlb_namespace::required_function();
But when I compile the project the linker says that tlb_namespace::required_function is an unresolved external symbol.
How can I succesfully build this kind of project?
EDIT:
I have used the same type library in a Dummy VBA access project. I have added the reference to the type library and I have noticed that some of the function contained in the type library are correctly called. But some of them are not. VBA says It can't locate their entry point in the related dll.
Can this explain the unresolved external symbol when building c++ app?
I have also noticed that the failing function are declared in the tlb like this:
UPPER_function_name
but in the dll are declared like this:
Upper_function_name
Can this be the issue?
Is it possible to solve this kind of error directly modifying the binary tlb file or dll?
Use IDE to view TLB information.
Use this help : How to: View Type Library Information
At IDE : View-> Object Browser, click "..." Edit Custom Component Set, browse your TLB file and Add to view information.
Confirm namespace used for.
use the namespace to resolve the linker error:
example:
#import "<>" raw_interfaces_only
using namespace <>
this will resolve the problem
I am trying to create a dynamic library of the Armadillo linear algebra library, which is originally a header-only library, using VC++ 2010 on Win XP. I created a new project, added the source files, and created a .def file specifying to export only one Armadillo function (the Col class), and I get the LNK2001 error for the Col class. I can create a main and use Col just fine, so I think Col is being included correctly.
I have also tried using "__declspec(dllexport)" on the function definition and it compiles, but the function is not exported since using dumpbin shows nothing, and I can not use the .dll sucessfully. Am I missing something here?
As Armadillo is a C++ template library that uses expression templates, I don't think it's possible to create a DLL out of it.
The expression templates are executed (run) at compile-time by the C++ compiler, whenever compiling code that uses Armadillo classes. Whenever a C++ library uses expression templates (part of template metaprogramming), the library can be thought of as an extension to the C++ compiler.
All the Armadillo code is in headers. As such, even if you managed to export one of the classes (eg. the Col class), none of the associated mathematical machinery (eg. addition, multiplication, etc) would be exported, which is defined all throughout the other parts of the library.