奇奇怪怪的函数01

1、FindResourceA

1
2
3
4
5
6
7
8
9
10
11
12
HRSRC FindResourceA(
HMODULE hModule,
LPCSTR lpName,
LPCSTR lpType
);
FindResourceA function
Determines the location of a resource with the specified type and name in the specified module.
确定具有指定类型和名称的资源在指定模块中的位置。
hModule:处理包含资源的可执行文件的模块。NULL值则指定模块句柄指向操作系统通常情况下创建最近过程的相关位图文件。
lpName:指定资源名称。
lpType:指定资源类型。
返回值:如果函数运行成功,那么返回值为指向被指定资源信息块的句柄。为了获得这些资源,将这个句柄传递给LoadResource函数。如果函数运行失败,则返回值为NULL

2、SizeofResource

1
表示该函数返回指定资源的字节数大小。

3、LoadResource

1
2
LoadResource function
检索一个句柄,该句柄可用于获取指向内存中指定资源的第一个字节的指针。

4、__gmpz_init_set_str

1
2
3
4
5
其实就是 mpz_init_set_str int mpz_init_set_str (mpz_t rop, const char *str, int base) 函数:

这三个参数分别是多精度整数变量,字符串,进制。 这个函数的作用就是将 str 字符数组以 base 指定的进制解读成数值并写入 rop 所指向的内存。

mpz_init_set_str(b, “200000”, 10); //即 b=200000,十进制

5、 mpz_powm

1
2
3
4
5
mpz_powm (mpz_t rop, const mpz_t base, const mpz_t exp, const mpz_t mod) 函数:
其实就是计算 base 的 exp 次方,并对 mod 取模,最后将结果写入 rop 中, 这个运算的过程和RSA的加密过程一样。

mpz_powm(op1,op2,op3,op4); //求幂模函数 即 op1=op2^op3 mod op4;

6、 CreateThread

在C/C++中可以通过CreateThread函数在进程中创建线程,函数的具体格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadID
);
/*
参数的含义如下:
lpThreadAttrivutes:指向SECURITY_ATTRIBUTES的指针,用于定义新线程的安全属性,一般设置成NULL;

dwStackSize:分配以字节数表示的线程堆栈的大小,默认值是0;

lpStartAddress:指向一个线程函数地址。每个线程都有自己的线程函数,线程函数是线程具体的执行代码;

lpParameter:传递给线程函数的参数;

dwCreationFlags:表示创建线程的运行状态,其中CREATE_SUSPEND表示挂起当前创建的线程,而0表示立即执行当前创建的进程;

lpThreadID:返回新创建的线程的ID编号;
*/

如果函数调用成功,则返回新线程的句柄,调用WaitForSingleObject函数等待所创建线程的运行结束。函数的格式如下:

1
2
3
4
5
6
7
8
9
10
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
/*
参数的含义如下:
hHandle:指定对象或时间的句柄;

dwMilliseconds:等待时间,以毫秒为单位,当超过等待时间时,此函数返回。如果参数设置为0,则该函数立即返回;如果设置成INFINITE,则该函数直到有信号才返回。
*/

一般情况下需要创建多个线程来提高程序的执行效率,但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对一个内存地址进行写入操作,由于CPU时间调度的问题,写入的数据会被多次覆盖,所以要使线程同步。

就是说,当有一个线程对文件进行操作时,其它线程只能等待。可以通过临界区对象实现线程同步。临界区对象是定义在数据段中的一个CRITICAL_SECTION结构,Windows内部使用这个结构记录一些信息,确保同一时间只有一个线程访问改数据段中的数据。

使用临界区的步骤如下:

(1)初始化一个CRITICAL_SECTION结构;在使用临界区对象之前,需要定义全局CRITICAL_SECTION变量,在调用CreateThread函数前调用InitializeCriticalSection函数初始化临界区对象;

(2)申请进入一个临界区;在线程函数中要对保护的数据进行操作前,可以通过调用EnterCriticalSection函数申请进入临界区。由于同一时间内只能有一个线程进入临界区,所以在申请的时候如果有一个线程已经进入临界区,则该函数就会一直等到那个线程执行完临界区代码;

(3)离开临界区;当执行完临界区代码后,需要调用LeaveCriticalSection函数离开临界区;

(4)删除临界区;当不需要临界区时调用DeleteCriticalSection函数将临界区对象删除;

7、 CloseHandle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CloseHandle函数

  BOOL CloseHandle(
   HANDLE hObject
   );

  /*
  参数
  hObject :代表一个已打开对象handle。

  返回值
  TRUE:执行成功;
  FALSE:执行失败,可以调用GetLastError()获知失败原因。

  函数说明:
  关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread成功之后会返回一个hThread的handle,且内核对象的计数加1,CloseHandle之后,引用计数减1,当变为0时,系统删除内核对象。
  若在线程执行完之后,没有调用CloseHandle,在进程执行期间,将会造成内核对象的泄露,相当于句柄泄露,但不同于内存泄露,这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后,系统会自动清理这些资源。
*/

Closing a thread handle does not terminate the associated thread. To remove a thread object, you must terminate the thread, then close all handles to the thread.

1,线程和线程句柄(Handle)不是一个东西,线程是在cpu上运行的.....(说不清楚了),线程句柄是一个内核对象。我们可以通过句柄来操作线程,但是线程的生命周期和线程句柄的生命周期不一样的。线程的生命周期就是线程函数从开始执行到return,线程句柄的生命周期是从CreateThread返回到你CloseHandle()

2,所有的内核对象(包括线程Handle)都是系统资源,用了要还的,也就是说用完后一定要closehandle关闭之,如果不这么做,你系统的句柄资源很快就用光了。

3,如果你CreateThread以后需要对这个线程做一些操作,比如改变优先级,被其他线程等待,强制TermateThread等,就要保存这个句柄,使用完了在CloseHandle。如果你开了一个线程,而不需要对它进行如何干预,CreateThread后直接CloseHandle就行了。

所以 CloseHandel(ThreadHandle ); 只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了。并没有结束线程。