10/31/2007

LNK2028, LNK2019 without extern "C"

I wrote a Win32 dll in VS2005 and a CLR-Console client, the CLR-Console client is the caller of Win32 dll. In the Win32 dll, using /TC compiler option to build it and using /clr option to build the CLR-Console client. The all things is fine, such as 'dllexport/dllimport', 'Additional Include Deirectories' and 'Additional Dependencies'. But I got LNK2028 unresolved token and LNK2019 unresolved external symbol, the reason is I forgot using the extern "C" to include all dllexport functions.

10/23/2007

Reversing string in C

There is a example for reversing string in the Section 3.5 of K&R's 'The C Programming Language' . The example code look like this:
void reverse(char s[]) {

char c;
int i, j;

for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
c = s[i], s[i] = s[j], s[j] = c;
}
}

But the above code can be improved. There is 'Pointer Version':
void reverse(char *s) {
char *l = s;
char c;

while (*s++)
;
s -= 2;

while (l < s) {
c = *l;
*l++ = *s;
*s-- = c;
}
}

The *strrev* in C standard library implements the same functionality, but generally implements in assembly code.

10/20/2007

Item not found: Could not find this item! on Vista

When u try to remove a directory under the Vista GUI, u'll get 'Item not found: Could not find this item'. Or, u'll get 'The system cannot find the file specified' under the Vista command prompt.

Try the following:
1. Open the command prompt.
2. Execute *dir /x* to display 8.3 file name
3. Execute *rd filename* the filename 8.3 format that u got it in step 2.

10/18/2007

The #end joke

I found a joke when I publish my blog through the gmail. Wrote a blog which includes a piece of C/C++ code. Within that, the *# e n d i f* C/C++ directive had been used. So after send my blog, I got truncated blog content, Ha.

Because, u can use the *# e n d* flag in ur gmail in order to indicate blogger to truncate the content after *# e n d* flag. It's a joke.

Organize IA-32 machine code in C++ class

First, look the following code:

#include <iostream>

#pragma pack(push, 1)
class MachineCode {
public:
unsigned char jmp_;
unsigned long proc_;
};
#pragma pack(pop, 1)

typedef void (__stdcall *ProcCall)(void);

class Adapter {
public:
int Init(void* proc, void* pthis) {
thunk_.jmp_ = 0xE9;
thunk_.proc_ = (unsigned long)proc - ((unsigned long)pthis + sizeof(thunk_));

::FlushInstructionCache(::GetCurrentProcess(), pthis, sizeof(thunk_));

return (true);
}

ProcCall GetProcCaller(void) {
return (reinterpret_cast<ProcCall>(&thunk_));
}

static void DefProcCall(void) {
std::cout<<"in Adapter::DefProcCall.\n"<<std::endl;
}

private:
MachineCode thunk_;
};

Then, I use the following code to call X::DefProcCall function:

Adapter x;
x.Init (&Adapter::DefProcCall, &x);
ProcCall call = x.GetProcCaller();
call();

The all magic is at 'reinterpret_cast<ProcCall>(
&thunk_)' in GetProcCaller member function of Adapter class and two data members in MachineCode class. Directly, generates such IA-32 code 'call dword ptr [function-address]' when C++ compiler meet 'call()' statement. Because of the function-address exactly is the address of the thunk_ which is the first data member of Adapter class. So the machine code in thunk_ has been executed.

The jmp_ data member of MachineCode class stores 0xE9 that is 'jmp' instruction in IA-32. And the proc_ data member stores relative address since the ending address of the thunk_ which in Adapter class. So whole MachineCode class generate such IA-32 code 'jmp address'.

10/16/2007

[] Operator in IA-32 assembly code

[] bracket operator means get the content of the memory location, u can treat [location] as addressing expression.

The following C code:
int i;
i = 0x1234;

can be translate to assembly code which looks like this:
mov dword ptr [i], 1234h

the dword ptr means the content of variable i occupied 4 bytes. It is required because of IA-32 is byte addressable. And above mov instruction does not know how much storage requires for storing immediate number 1234h.

10/15/2007

Cannot install Microsoft Server 2003 SP2!

*update.inf*

1. net stop cryptsvc
2. ren %systemroot%\system32\catroot2 old-catroot2
3. net start cryptsvc

10/14/2007

Manipulate bits in C

1. Definition:
const int FIRST = 1 << 0;
const int SECOND = 1 << 1;
const int THIRD = 1 << 2;

Why defines the bit flag like this? Oh, just for clarity.

2. Setting bit flag:
int flags = 0;

flags |= FIRST;
flags |= SECOND;
flags |= THIRD;

if (flags & FIRST) {
printf("FIRST bit has been set.\n");
} else if (flags & SECOND) {
printf("SECOND bit has been set.\n");
}
...

3. Clearing bit flag:
flags &= ~FIRST;
flags &= ~SECOND;
...