I need to use RawInput api calls from under the old compiler
which is pre xp (it is borland 5.5 specifically - and do not tell
me to use other compiler it is out of question, I need to use it)
Ist headers winuser.h and user32.lib do not contain the raw input
calls, never header and user32.lib from other compilers do.
So it is achieveable to use such external rawinput .h definitions
and link it against newest user32.lib?
I am not so much experienced in linker stuff. Definitions compile
but I do have unresolved externals at link
Error: Unresolved external '__stdcall GetRawInputDeviceList (tagRAWINPUTDEVICELIST *, unsigned int *, unsigned int)' referenced from C \CODE2\PROGRAM\MAIN.OBJ
Error: Unresolved external '__stdcall RegisterRawInputDevices(const tagRAWINPUTDEVICE *, unsigned int, unsigned int)' referenced from C:\CODE2\PROGRAM\MAIN.OBJ
substitution of old user32.lib with new user32.lib seem to give no effect (even
renaming it out seem to has no effect, and it seems like compiler do not touch user32.lib at all (?)
How to make it work, much tnx for advice how to resolve this (and to not tell me
i need newer compiler, i need to do it with this old)
(fire)
// edit : fixed my mistake typo winuser.lib to user32.lib (i meant user32.lib)
When you need to call APIs which do exist on some Windows platforms and not on other ones, then you must NOT bind to the associated LIB statically but dynamically (using LoadLibrary and GetProcAddress). Another mechanism would be to use Delay-loaded Libraries.
GetRawInputDeviceList and RegisterRawInputDevices are both in user32.lib not in winuser.lib
http://msdn.microsoft.com/en-us/library/windows/desktop/ms645598(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms645600(v=vs.85).aspx
those pages also state that you only need to include windows.h (and not winuser.h)
Related
I am writing lib files in VS that have to be imported into CVI.
Recently a linker problem occured.
It says that _allmul() is an undefined symbol.
_allmul() and freinds are implemented as calls to the CRT library functions to handle various 64bit operations.
The lib file that i write is static because i want all the code to live inside it.
Linking with VS is no problem and all unittests pass.
Linking with the CVI-IDE leaves the CVI Linkter complaining about an unresolved _allmul().
I thougth that setting the /MT switch in VS is enough to make the CRT link statically, this seems to be wrong.
Why is my assumtion wrong?
How can i link the CRT calls statically?
Edit:
Here is a short demo of a project that i can compile in VS2010 but that i can not link to in CVI
The following is compiled as a LIB project:
HEADER
void print( unsigned A, unsigned B );
CODE
#include "MyprintInterface.h"
#include <stdio.h>
void print( unsigned A, unsigned B ){
long long copyA = ( long long ) A;
long long copyB = ( long long ) B;
printf_s( " %lli * %lli = %lli ", copyA, copyB, copyA * copyB );
// copyA * copyB -> this invokes allmul
// printf_s this is a ms specific function
}
This is a little late, but maybe it will help someone else.
I had very similar experience when using the gSoap toolkit with LabWindows/CVI. The toolkit generates ANSI C bindings used in creating web service clients or servers. However it sometimes generated versions of MS functions (some deprecated) that were prototyped slightly different than those in CVI. Solving this was kind of tedious, but generally followed these steps:
1) install appropriate Microsoft SDK onto your dev box. Here is one option for Microsoft SDKs. (There are others, Google it)
2) search MSDN website for the unresolved symbol to determine what .lib/.h support it. (MSDN list of variations of sprintf, for example)
3) include any required .lib/.h files.
4) make sure msvcr80.dll or msvcr100.dll (or other as appropriate) are visible to your executable. (i.e. place either in the executable run-time directory, or in the system directory.)
In addition to this I had to bring some of the #defines from the header files supporting file write/read functions, just
for example:
#define _O_TEXT 0x4000 /* file mode is text (translated) */
#define _O_BINARY 0x8000 /* file mode is binary (untranslated) */
And: (Requires Microsoft Platform SDK be installed
c:\program files\microsoft platform sdk\include\crt (copied to project dir and included in project))
fcntl.h (definition for file mode etc., _O_BINARY)
float.h (definition for isnan etc.)
io.h (definition for setmode etc.)
Also, there is an example CVI project with source code illustrating what I have described above, (including using crt) here.
[EDIT]
Regarding COFF compatible .libs when using third party libraries with respect to LabWindows/CVI - Read the posts here.
[EDIT 2]
Once you install the Windows SDK, the headers for everything in msvcrxxx.dll will be on your system. But for finding .h dependancies of a specific API call I typically have good luck just searching for it on Google: i.e. for sprintf_s et. al., the first link returned was this. It includes notes on how to use sprintf_s including source code.
As for allmul issues, I have not run into this before, but this guy did.
I have a problem with SHGetFolderPathA in Visual Studio 2010 (Windows Forms).
I included to project ShlObj.h and added for button this code:
char SciezkaCookies[MAX_PATH];
HRESULT hr = ::SHGetFolderPathA(0, CSIDL_APPDATA, 0, SHGFP_TYPE_DEFAULT, SciezkaCookies);
But when i try compile my project, Visual return errors:
error LNK2028: unresolved token (0A000012) "extern "C" long stdcall
SHGetFolderPathA(struct HWND *,int,void *,unsigned long,char *)"
(?SHGetFolderPathA##$$J220YGJPAUHWND__##HPAXKPAD#Z) referenced in
function "private: void __clrcall VoxPopuli::Form1::start_Click(class
System::Object ^,class System::EventArgs ^)"
(?start_Click#Form1#VoxPopuli##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
and
1>VoxPopuli.obj : error LNK2019: unresolved external symbol "extern
"C" long stdcall SHGetFolderPathA(struct HWND *,int,void
*,unsigned long,char *)" (?SHGetFolderPathA##$$J220YGJPAUHWND__##HPAXKPAD#Z) referenced in
function "private: void __clrcall VoxPopuli::Form1::start_Click(class
System::Object ^,class System::EventArgs ^)"
(?start_Click#Form1#VoxPopuli##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z)
I'm looking for solutions in google, but all examples is not working ;/
Thanks for help!
Calling native winapi functions like SHGetFolderPath() is fine from C++/CLI, that's what the language is good at, but you do have to keep the linker happy yourself. Use the MSDN Library article for the function (not today, site has been down all week). At the bottom of the article it lists "Header", that's how you found out that you needed to tell the compiler about shlobj.h. It also lists "Import library", that's what you need to tell the linker. The import library tells the linker what DLL needs to be loaded at runtime to call the function.
Project + Properties, Linker, Input, Additional Dependencies. Add "shell32.lib"
Or you do it in your source code with a #pragma, a way to pass link instructions to the linker:
#include <shlobj.h>
#pragma comment(lib, "shell32.lib")
It should be said, this is definitely one api function that you really want somebody else to have to deal with. Note how the MSDN Library article also says that the function is deprecated. There's been a lot of flux in standard folder paths across Windows versions. You have the "someone else" readily available in a .NET app, Environment::GetFolderPath() does this for you. Also saves you from the hassle of having to deal with different string types.
You must have declared it yourself to avoid including the Windows headers- not that I blame you for doing that- but you have mangled the name, so the linker cannot resolve it from the native library.
Oh, you're in C++/CLI? Maybe the compiler flat out won't like the native call into managed code, then.
I'd avoided using native functions if .NET solution is possible. Try to use
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
Both native and .NET approaches are discussed here:
http://bytes.com/topic/c-sharp/answers/269259-my-documents-path-c
I want to build a DLL to use it as an IIS/ISAPI application. So far so good. It works. However, I have to drag arround the runtime dll and other dependencies (like some boost libraries).
I would like to make a single DLL (in order to ease the deployment on multiple servers).
So I changed the switch from /MD to /MT. However, now I get errors of duplicate symbols during link. For example :
msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::`vbase destructor'(void)" (??_D?$basic_ostream#DU?$char_traits#D#std###std##QAEXXZ) already defined in gateway.obj
I'm puzzled that /MD or /MT are compiler flags and not linkers flags. And it could in some way explain why I get duplicated symbols (as the will be included in each .obj).
So the question is: how do I configure visual studio 10 in order to get a dll that includes all its dependencies.
The /MD and /MT switches only apply to the Microsoft C runtime library and not 3rd party libraries. This documentation gives some information on why it is a compiler switch (they cause different defines to be created during the compilation).
Pulling 3rd party DLLs directly into your own DLL as static libraries is probably not a simple process unless static libraries already exist. I don't know of any standard method for turning a DLL into a static library. A quick Internet search indicates that there exist tools that claim to do that process (my quick search did not turn up any free ones). But I think the most robust solution would be to use existing static libraries if you can. I believe you can build static versions of the Bools libraries, which you could then specify in your link statement in Visual Studio (as opposed to naming the libraries for the DLLs).
I am compiling a DLL twice (once for x86, once for x64) and I have set /ENTRY to "DllMain". I am using the /MT runtime library option to statically link against the runtime library. This all work fine when doing the x86 build, but the x64 build fails with this:
error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
{project directory}\LIBCMT.lib(crt0.obj)
Why does this work for the x86 build and not the x64 build? Is there something I am missing here?
Not a direct answer but it may be strictly related: as said in the comment, you should avoid changing the entrypoint in that way: normally the real entrypoint is taken by a "fake" DllMain provided by the CRT to initialize its internal data structures (as explained here), so you're bypassing it. Probably the size reduction is due to CRT init code being removed.
Your dll is working with a non-initialized CRT, which is very bad. You should leave the default entrypoint, which, incidentally, should solve your problem.
By the way, notice that actually you could make a dll without the CRT (and it would become really small), but you shouldn't use the CRT at all, without even linking against it (/NODEFAULTLIB switch). This means that you could just use libraries you explicitly link against (e.g. the Windows API), but I suspect you would lose several C++ features (I think at least exceptions and RTTI).
This could be a silly question, but are you sure you're linking as a DLL in the x64 case (ie. specifying the /DLL switch) - since the complaint is about main, I wonder whether it's trying to link as a an executable?
When developing and deploying native Windows applications, I often need to install a runtime before being able to run my binary, or statically link the library with my binary. For instance, after building a "Win32 Console" project with Visual Studio 2008, attempting to run the program on a fresh Windows 7 image results in:
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
Issues like this one have been brought up in other posts on StackOverflow.
How does one develop applications that don't require runtimes that aren't already on the target OS (i.e. don't require installing redistributable packages or private/shared side-by-side assemblies)? How does one avoid using msvc[mpr]90.dll and just use the Windows API in \windows\system32*.{dll,sys}?
I'm thinking along the lines of the code that comes out of the demoscene, but that's frequently not made available.
Others have already responded with respect to linking CRT statically. If you also want a small binary at the same time, then your best bet is forego CRT entirely, and use only Win32 API functions as much as possible. You'll still get some CRT code, most notably related to startup (i.e. that which calls main) and shutdown (atexit handling etc), but otherwise the linker won't link CRT functions that you do not use.
You can avoid linking CRT altogether by using /Zl compiler switch. This means that main will no longer work, however - you'll need to define WinMain (name doesn't matter, but signature must match, and it must be __stdcall), and you will have to specify the name of your WinMain-like function as an entry point via linker /entry: switch. This will save you ~30Kb of CRT code (tested on a .cpp with an empty main).
If you go the latter route, you might also have to deal with issue of compiler intrinsics. There are some functions that are nominally defined by the CRT (and declared in its headers), but which are treated specially by the compiler, so that it inserts optimized assembly instructions at the point of the call where possible - examples are memset, strlen, and a good chunk of functions in <math.h>; a complete list can be found here. Since you don't have CRT, if you need these functions, or could avoid it but prefer the intrinsic because of improved performance (hard to do better than memset, for example), then you have to declare them yourself, and use #pragma intrinsic. E.g.:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
The above can be compiled with:
cl /c /Zl foo.cpp
link /entry:main foo.obj
Link the CRT statically via the /MT switch (and likewise MFC, if you're using it).
Static linking limits what you can do with DLLs somewhat, but for simple executables it works like a charm. (And if you're shipping DLLs, you can always ship private assemblies anyway.)
Use the static CRT. This doesn't create a dependency on msvc*.dll. The CRT is linked directly into your program. This doesn't create dependencies, but does increase the size of your executable.
More info on different CRT options here.
Statically link the runtime. MS Visual C++ has option /MT for that (default is /MD)
I think one way to do this is to just not use Visual Studio and instead rely on the command line SDK tools. (You can alternatively figure out how to config VS to do what you want, but that seems harder.) E.g.:
cl /c app.cpp
link app.obj ws2_32.lib