UINT32 compiler version mismatch - Linking to legacy library - c++

I am trying to link a DLL but I am constantly running into issues with UINT32.
The library is compiled against the 4.1 version of the Visual Studio compiler. The interface for my component (which was 4.1 and I am now porting to 2012) is defined with many UINT32s in it. In VC4.1 UINT32 is not defined by the compiler and so it was typedefed to unsigned long by the programmer, but from VC6 onwards UINT32 is defined as unsigned int. This makes my life hard.
My initial reaction was to try replacing all UINT32 in the interface with unsigned long and recompiling. This works as the function signatures are the same. However an unsigned long in 2012 is 64 bits wide... not 32 bits. This is not a problem in most cases but I foresee possible problems with flag parameters and return types.
What I am wondering is if I have missed a more obvious solution for this. I thought of defining a different type
typedef OAM_UINT32 unsigned long //in the library
typedef OAM_UINT32 unsigned int // in my component
But then the problem is going to be the same as what I have already with my two definitions of UINT32... right?
Any help would be much appreciated.
The Problem
Client code
#include <oam_if.h>
....
UINT32 uuid = getSomeLocalUserId();
UINT32 dwOamRetVal = dwOamGetUserDetails( uuid ); // LINK ERROR: Symbol not found
oam_if.h
UINT32 dwOamGetUserDetails( UINT32 idOfUser );
When the library (OAM) is compiled the UINT32 value is evaluated as an unsigned long. When the client component is compiled, UINT32 is evaluated as unsigned int. The linker complains because it has a symbol defined in the OAM library for dwOamGetuserDetails which rakes and returns an unsigned long, but the client is calling a function which according to it should take an unsigned int.
So while their respective inputs are unsigned numbers both 32 bits long, the signature of the function is different and the linker complains.
The only way I can see to fix it is to define everything as unsigned long directly. However then OAM will be using a 32 bit long number but the client will be using a 64 bit number!
Sample of Linker Error
error LNK2001: unresolved external symbol "public: virtual unsigned long __thiscall Message::getCallId(void)const " (?getCallId#Message##UBEKXZ) oam.lib(OAM_SsRequest.obj)
This is actually a callback from the library to the component, so in this case it is looking for a signature that matches UINT32 as defined by the libary (unsigned long) but the component is defining an unsigned int for its callback.

Related

Trying to write a DLL for wallhack usw

I'm trying to write a DLL file that I can inject into a game. I'm pretty far but when I try to compile the code I always get the error
Error LNK2001 Unresolved external symbol "" unsigned char * __cdecl Detours :: X86 :: DetourFunction (unsigned char *, unsigned char *, enum Detours :: X86Option) "(? DetourFunction # X86 # Detours ## YAPAEPAE0W4X86Option # 2 ## Z ) ".
The detours folder I use is from here:
https://github.com/Nukem9/detours
but the Detours.h file was broken because I couldn't use uint8_t so I replaced the code in there with the code from that file:
https://github.com/Nukem9/VMWareClient/blob/master/vmware_client/detours/Detours.h
The codline where I think the problem is:
oEndScene = (EndScene)Detours::X86::DetourFunction((uint8_t*)d3d9Device[42], (uint8_t*)hkEndScene);
but for those who are interested, I can post the whole code here. Just tell me in the comments. The whole code is 256 lines long
You can't just replace function definition:
uintptr_t DetourFunction(uintptr_t Target, uintptr_t Detour, X86Option Options = X86Option::USE_JUMP);
with
uint8_t *DetourFunction(uint8_t *Target, uint8_t *Detour, X86Option Options = X86Option::USE_JUMP);
Why can't you use uint8_t? Can't you just add:
typedef unsigned char uint8_t;

Define optional char / wchar_t pointer parameter in MIDL

I have an existing Win32 C++ DLL, which needs to be accessed by a VB6 client. One of the exported functions is defined as follows:
__declspec(dllexport) long __stdcall Foo(long nId, LPCWSTR pszwPath = nullptr);
Unfortunately, VB6 always converts strings to ANSI when calling DLL functions via a Declare statement. In order to bypass this limitation, I have embedded a type library, which features the following signature for the function:
[uuid(...)]
library FooLib
{
[
helpstring("FooLib"),
dllname("Foo.dll")
]
module FooMdl
{
[entry("Foo")]
long __stdcall Foo([in] long nId, [in,unique,string,defaultvalue(0)] LPCWSTR pszwPath);
}
};
This won't compile however, as MIDL generates the following error:
error MIDL2020 : error generating type library : AddFuncDesc failed : Foo
My next attempt involved utilizing the optional attribute:
long __stdcall Foo([in] long nId, [in,unique,string,optional] LPCWSTR pszwPath);
While this type library can be compiled successfully, the VB6 client crashes with an access violation as soon as the optional string value is omitted.
I am aware that I could change the LPCWSTR argument to a BSTR type, thereby remedying the problem. However, this would also require me to change the signature and implementation of the existing DLL.
Is it therefore possible to define a char / wchar_t pointer argument as optional or with a NULL default value? Or am I simply out of luck here?

Char Followed by a char is illegal (qglobal.h)

I searched this forum already and found a same question but it didn't solve and not even gave any clue in solving my problem. I am doing one project in which i am using Templates.
Firstly i used C++ map like this
typedef map<int ,cal_point*> p_mMap2D;
and it worked perfectly. Then i tried to make a GUI using Qt, but when i used "QMap", it gave an error that
typedef QMap<int ,cal_point*> p_mMap2D;
Error 25 error C2632: 'char' followed by 'char' is illegal C:\Qt
\4.7.4\include\QtCore\qglobal.h 897
Then i tried to use only map as i used before but still it is giving error. I searched net but didn't get any clue related to it. If i don't use Qt then its working perfectly.
Code from qtglobal.h
QT_BEGIN_INCLUDE_NAMESPACE
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
QT_END_INCLUDE_NAMESPACE
Inside /src/corelib/global/qglobal.h Qt 4.8.5 contains following strings:
# define QT_BEGIN_INCLUDE_NAMESPACE }
# define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
And when preprocessor expands this macro with for example QT_NAMESPACE=qt result will be:
}
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
namespace qt {
Looks like an error of definition QT_BEGIN_INCLUDE_NAMESPACE and QT_END_INCLUDE_NAMESPACE.
It is hard to tell because you have not included the definition of cal_point*, but the problem is where it is defined or somewhere among those lines. Check them. It might be in an external file that makes it break, and so on.

C++ link error LNK2005

I am new to C++ programing and I'm trying to make a program that simulates Conway's game of life. I'm almost done but when I made each function have it's own file I keep on getting this linker error.
1>algorithm_change.obj : error LNK2005: "unsigned short height" (?height##3GA) already defined in algorithm.obj
My code is at https://github.com/rupertsteel/Life/tree/master/Life
Without looking at the code, do you have a global unsigned short height; in any header file? If yes, replace that with extern unsigned short height; and put a unsigned short height; in a source file that includes the specific header.
A few comments:
1) array_length in life.h needs to be externed
2) All the externed variables (width, height, ticks, count_array, change_array, error_check, algorithm_length, array_length) need to be defined somewhere.
In your code you've basically told the compiler that those variables exist somewhere but haven't actually placed them in existence anywhere. In one of your .cpp files in the global scope you need to put:
unsigned short int width;
unsigned short int height;
unsigned long int ticks;
unsigned short int count_array[10923][10923];
bool change_array[10923][10923];
int error_check;
unsigned long int algorithm_length;
unsigned long int array_length;
Which is exactly the same as what you have in life.h, except without the extern keyword. This will actually create the variables, as opposed to now where they have no concrete implementation.
If you make the changes I suggest your code will compile (tested using gcc). That being said, the actual error you're seeing doesn't make sense.

VS2008 Link Error Using SafeInt3.hpp in 64bit mode

I have the below code that links and runs fine in 32bit mode -
#include "safeint3.hpp"
typedef SafeInt<SIZE_T> SAFE_SIZE_T;
SAFE_SIZE_T sizeOfCache;
SAFE_SIZE_T _allocateAmt;
Where safeint3.hpp is current version that can be found on Codeplex SafeInt. For those who are unaware of it, safeint is a template class that makes working with different integer types and sizes "safe". To quote channel 9 video on software - "it writes the code that you should".
Which is my case. I have a class that is managing a large in-memory cache of objects (>6gb) and I am very concerned about making sure that I don't have overflow/underflow issues on my pointers/sizes/other integer variables. In this use, it solves many problems.
My problem is coming when moving from 32bit dev mode to 64bit production mode. When I build the app in this mode, I'm getting the following linker warnings -
1>cachecontrol.obj : warning LNK4006: "bool __cdecl IntrinsicMultiplyUint64(unsigned __int64 const &,unsigned __int64 const &,unsigned __int64 *)" (?IntrinsicMultiplyUint64##YA_NAEB_K0PEA_K#Z) already defined in ImageInRamCache.obj; second definition ignored
1>cachecontrol.obj : warning LNK4006: "bool __cdecl IntrinsicMultiplyInt64(__int64 const &,__int64 const &,__int64 *)" (?IntrinsicMultiplyInt64##YA_NAEB_J0PEA_J#Z) already defined in ImageInRamCache.obj; second definition ignored
While I understand I can ignore the error, I would like either (a) prevent the warning from occurring or (b) make it disappear so that my QA department doesn't flag it as a problem. And after spending some time researching it, I cannot find a way to do either.
The problem is that inside safeint3.hpp, the code looks like this:
bool IntrinsicMultiplyUint64( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64* pRet )
{
....
}
This means every translation unit that includes safeint3.hpp will get a definition of IntrinsicMultiplyUint64. If you are willing to modify that file, you can make those functions inline:
inline bool IntrinsicMultiplyUint64( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64* pRet )
{
....
}
Are these function declared and defined in the header file and not declared as inline by any chance?
It looks like they're quasi-inlined but the symbols are visible outside the object file, which they shouldn't be.
If that's the case, simply declaring them as inline should fix the issue.
Regarding your question about disabling the warning, this should do it:
#pragma warning(disable:4006)