I need to build a purchased library (with source) that was built in VC 2010. We have to build with VC6. I ran across signed and unsigned "long long". I am using "_int64" for the signed type but was unable to find anything for the unsigned type. Has anyone run across a solution? Apologies if this is documented, I have had no luck in finding anything.
__int64 is a vendor-specific base type. It can be combined with the unsigned modifier, just like:
unsigned char unsigned __int8
unsigned short unsigned __int16
unsigned int unsigned __int32
unsigned long unsigned __int32
(unsigned long long) unsigned __int64
(unsigned __int128)
Where the parenthesized names are not available in VC6, but are supported in the current version of Visual C++.
Related
I'm upgrading a device driver from a 32bit RHEL 2.6.32 to 64bit RHEL 2.6.33.9.
I have a program that talks to that driver using ioctl. It works perfectly when both the driver and the program are either 64bit or 32bit. But when the driver is 64bit, and my program is 32 bit, the ioctl command received by the driver (in compat_ioctl) does not match the values defined by the _IOR and _IOW macros.
In my driver's switch statement, the default case prints out the values of all the valid commands, which are 1-12. The 32bit ioctl command is nowhere near those values.
Can someone tell me what would cause the command from a 32bit user program to be messed up when received in a 64bit driver?
Here's some of the code: I had to type it in; the code is on a secured system without internet access, so please forgive any typos. It actually does comile and run!
// IOCTL commands from the include file - most omitted
// ...
#define PORTIO_GET_IRQ_CNT_CMD 10
#define PORTIO_CLR_IRQ_CNT_CMD 11
#define PORTIO_GET_IRQ_TIME_CMD 12
#define PORTIO_IOCTL 'k' // magic number for ioctl
// IOCTL Macros
#define PORTIO_GET_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)
Here's the 32 bit compatible IOCTL routine, from portio.c. I've confirmed that this is being called only when my program is compiled as 32bit, and the driver is 64bit.
static long portio_compat_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned char cmd_number;
int cmd_size=0;
//...
cmd_number = _IOC_NR( cmd );
cmd_size = _IOC_SIZE( cmd );
printk( KERN_ALERT "Portio Compat IOCTL number,size = %d,%d, cmd_number, cmd_size );
//... Switch statement and cases, based on cmd_number
}
The output looks like this:
Portio Compat IOTCL number,size = 224,3157
Of course, the code expects IOCTL numbers from 1-12, and sizes around 4 or 8. That's exactly what comes back when the code and driver are both either 64bit or 32bit.
It seems to me that your function compat_ioctl takes too many parameters. Look at other definitions in the Linux kernel:
long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
http://lxr.linux.no/#linux+v3.5.3/block/compat_ioctl.c#L654
#define PORTIO_GET_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)
change unsigned long to unit64_t (fixed data type)
remove all pointer from ioctl macro arguments,
have :
.compat_ioctl
.unlocked_ioctl in kernel pointing to same function.
ostream &stream;
stream.write(SomeUnsignedCharStar, intSize);
error C2664 cannot convert parameter 1 from const unsigned char * to const char *
Is there an overload write for const unsigned char *?
I do not want to change SomeUnsignedCharStar because it is everywhere in the legacy code I inherited. This was compiled on VC6 with no complain. I am slowly upgrading the code to VS2003 and then VS2010 evantually.
What is the easiest and cleanest fix?
You can cast this without any issues. Strict aliasing allows casting pointers between unsigned and signed versions of the same type, as well as casting from any type to const char*, so you're safe here.
I want to initialize bits of a variable of unsigned char with a string of binary digits, but I don't know how to do it.
From your comments, it seems like you want to parse an ASCII string of binary digits. This is how you do that:
#include <stdlib.h>
const char* binary = "10001001";
char* next;
unsigned char value = strtoul(binary, &next, 2);
if (*next) { /* conversion failed */ }
unsigned char s[] = "How now brown cow.\n";
I am trying to create a JNI wrapper for a C library that depends on the ICU libraries (libicuuc.so and libicui18n.so).
I tried building ICU4C in my NDK (both standard and CrystaX versions, on a Mac OS X machine) and kept running into linking issues like this:
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/udata.o: In function `openCommonData':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/udata.c:836: undefined reference to `icudt42_dat'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strFromWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:365: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:415: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:314: undefined reference to `wcstombs'
/Users/kyip/KyVmShared/KyAndroid/myproject/obj/local/armeabi/objs/icuuc/ustr_wcs.o: In function `_strToWCS':
/Users/kyip/KyVmShared/KyAndroid/myproject/jni/icu4c/common/ustr_wcs.c:164: undefined reference to `mbstowcs'
collect2: ld returned 1 exit status
I also tried the suggestion given at unicode support in android ndk but no luck. I got stuck at:
arm-eabi-g++ -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -D_REENTRANT -I../common -I../../icu/source/common -I../../icu/source/i18n "-DDEFAULT_ICU_PLUGINS=\"/usr/local/lib/icu\" " -DU_COMMON_IMPLEMENTATION -DHAVE_CONFIG_H -I/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/ -O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=0 -DU_GNUC_UTF16_STRING=0 -fno-short-enums -nostdlib -fPIC -DU_COMMON_IMPLEMENTATION -std=c++0x -fvisibility=hidden -c -o errorcode.ao ../../icu/source/common/errorcode.cpp
In file included from ../../icu/source/common/unicode/ptypes.h:23,
from ../../icu/source/common/unicode/umachine.h:52,
from ../../icu/source/common/unicode/utypes.h:36,
from ../../icu/source/common/errorcode.cpp:17:
/ky/crystax/android-ndk-r4-crystax/build/platforms/android-8/arch-arm/usr/include/sys/types.h:122: error: 'uint64_t' does not name a type
make[1]: *** [errorcode.ao] Error 1
make: *** [all-recursive] Error 2
Any help would be appreciated.
It seems that two files are involved in this issue. icu/source/common/unicode/ptypes.h which calls sys/types.h includes
#if ! U_HAVE_UINT64_T
typedef unsigned long long uint64_t;
/* else we may not have a 64-bit type */
#endif
By including sys/types.h from Android, we involve (near line 122/124)
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
typedef uint64_t u_int64_t;
#endif
It seems that uint64_t has not been declared when it is assigned to u_int64_t. Indeed, sys/types.h includes stdint.h which has the following:
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
typedef __int8_t int8_t;
typedef __uint8_t uint8_t;
typedef __int16_t int16_t;
typedef __uint16_t uint16_t;
typedef __int32_t int32_t;
typedef __uint32_t uint32_t;
#if defined(__STDC_INT64__)
typedef __int64_t int64_t;
typedef __uint64_t uint64_t;
#endif
Likely STRICT_ANSI is not defined. Seems like this is a bug in the Android code in sys/types.h. If STDC_INT64 is not defined, it will not define uint64_t so it can't define u_int64_t. Perhaps the real solution is to have sys/types.h modified so that it has
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
$if defined(__STDC_INT64__)
typedef uint64_t u_int64_t;
#endif
#endif
If you fix this, the next error will be in cstring.h:109
icu/source/common/cstring.h:109: error: 'int64_t' has not been declared
If you instead #define STDC_INT64 in common/unicode/ptypes.h it will go substantially farther, but will end at
icu/source/common/ustrenum.cpp:118: error: must #include <typeinfo> before using typeid
with more info here: http://groups.google.com/group/android-ndk/browse_thread/thread/2ec9dc289d815ba3?pli=1 but no real solutions
I also had this issue:
undefined reference to `mbstowcs'
You should build and link with higher version of android api.
Note:
I tried to link it with libraries from android-ndk/platforms/android-4... I had thought that 4 is version of Android, but 4 is version of Android API. And Android API 4 corresponds to Android 1.6 witch is very very old there is really no mbstowcs function in libc
Here is how i solved the problem. It is dirty but it works. The lib got compiled:
1. file: /icu4c/common/cwchar.h
comment out the #if U_HAVE_WCHAR_H and the respective #endif so the <wchar.h> is always included.
replace the previous uprv_wcstombs definition with:
#define uprv_wcstombs(mbstr, wcstr, count) U_STANDARD_CPP_NAMESPACE wcs2mbs(mbstr, wcstr, count)
replace the previous uprv_mbstowcs definition with:
#define uprv_mbstowcs(wcstr, mbstr, count) U_STANDARD_CPP_NAMESPACE mbs2wcs(wcstr, mbstr, count)
2. file: /icu4c/common/ustr_wcs.cpp
somewhere at the top, under the already existing includes add the line:
#include "../wcsmbs.h"
3. create new file "icu4c/wcsmbs.h"
size_t mbs2wcs(wchar_t * __ restrict pwcs, const char * __ restrict s, size_t n)
{
mbstate_t mbs;
const char *sp;
memset(&mbs, 0, sizeof(mbs));
sp=s;
return (mbsrtowcs(pwcs,&sp,n,&mbs));
}
size_t wcs2mbs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n)
{
mbstate_t mbs;
const wchar_t *pwcsp;
memset(&mbs,0,sizeof(mbs));
pwcsp = pwcs;
return (wcsrtombs(s,&pwcsp,n,&mbs));
}
Hope it helps.
There has been an effort to provide NDK wrappers for the ICU libraries that are part of the system: https://android-review.googlesource.com/c/153001/.
How do I compile assembly code in a separate file?
If my function is of the type "void __fastcall foo(unsigned long long, unsigned long long, unsigned long long, unsigned long long&, unsigned long long&)", how do I implement this in my .asm file?
.code
foo PROC
; do stuff here
foo ENDP
end