windows 定义的指针类型 (详细)

本文详细介绍了Windows编程中CHAR、TCHAR、WCHAR等指针类型的定义和使用,包括UNICODE和UNALIGNED相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

windows 编程时会遇到下面各种指针类型,它们都是通过typedef 定义的。
阅读完本文的正文后,就可以读懂下面列出的所有的数据类型。
CHAR、TCHAR、WCHAR、wchar_t、
指针类型:
ANSI:PCHAR、PCH、LPCH、PSTR、LPSTR、NPSTR、PCSTR、LPCSTR、LPUSTR、等等
UNICODE: PWCH、LPWCH、PWSTR、NWSTR、LPWSTR、LPCWSTR、PCWSTR、等等
Type Independent: PTCH/LPTCH/LPTSTR/LPCTSTR/LPTUSTR、等等

以下代码来自于winNT.h 和 tchar.h。

 

 

 

 

 

### C++ 中定义函数指针类型并调用 C 语言接口 #### 函数指针定义 在C++中,函数指针用于存储函数的地址以便稍后通过该指针调用函数。定义一个函数指针的方式与C语言非常相似,但需要考虑到C++特有的特性,尤其是当涉及到跨语言调用时。 例如,如果有一个C语言函数`int add(int x, int y)`,可以在C++中定义与其匹配的函数指针: ```cpp // 定义一个指向接受两个int参数并返回int值的函数的指针 int (*funcPtr)(int, int); ``` 这里的关键在于括号的位置——`( *funcPtr )`表明这是一个指针而非普通的函数声明[^1]。 --- #### 使用 `typedef` 简化语法 为了使代码更加清晰易读,推荐使用`typedef`来简化复杂的类型表达式。对于上面的例子来说,可以这样做: ```cpp typedef int (*FuncType)(int, int); // 创建一个新的类型 FuncType 表示一种特定签名的函数指针 FuncType funcPtr; // 声明了一个 FuncType 类型的变量 funcPtr ``` 这种方式不仅减少了重复冗长的代码书写工作量,还提高了维护性和可理解度[^2]。 --- #### 跨语言调用注意事项 由于C++会对符号进行重命名(即所谓的“名字修饰”),这可能会导致链接阶段出现问题,因为C编译器并不做同样的事情。为了避免这种情况发生,在包含任何来自C头文件的内容之前应当包裹以`extern "C"`块: ```cpp #ifdef __cplusplus extern "C" { #endif #include "some_c_header.h" // 这里包含了纯C风格的APIs #ifdef __cplusplus } // extern "C" #endif ``` 如此一来就告诉了C++编译器不要改变那些标志符的名字格式,从而允许两者之间的无缝协作[^3]。 --- #### 实际应用案例 假设有这样一个场景:我们需要从C库加载动态链接库(DLL),并通过获取导出函数地址实例化它们供后续操作之用。下面是具体实现步骤之一部分摘录: **C Library Example (`libexample.so` or `.dll`)** ```c // example.c int subtract(int a, int b) { return a - b; } void greet(const char* name) { printf("Hello %s!\n", name); } ``` **Corresponding Header File For Use In C++ Project** ```cpp // example_api.hpp #pragma once #ifdef __cplusplus extern "C" { #endif int subtract(int a, int b); void greet(const char* name); #ifdef __cplusplus } // extern "C" #endif ``` **Loading And Invoking Functions Dynamically Within A C++ Program** ```cpp #include <iostream> #include <dlfcn.h> // POSIX standard dynamic loading API on Unix-like systems. // On Windows you'd use LoadLibrary/GetProcAddress instead. using SubtractFunction = int(*)(int, int); using GreetFunction = void(*)(const char*); int main() { void* handle = dlopen("./libexample.so", RTLD_LAZY); if (!handle) { std::cerr << "Cannot open library: " << dlerror() << '\n'; return EXIT_FAILURE; } // Reset errors dlerror(); // Load the symbols SubtractFunction sub_func = reinterpret_cast<SubtractFunction>(dlsym(handle, "subtract")); const char* error = dlerror(); if (error != nullptr) { std::cerr << "Cannot load symbol 'subtract': " << error << '\n'; dlclose(handle); return EXIT_FAILURE; } GreetFunction grt_func = reinterpret_cast<GreetFunction>(dlsym(handle, "greet")); error = dlerror(); if (error != nullptr) { std::cerr << "Cannot load symbol 'greet': " << error << '\n'; dlclose(handle); return EXIT_FAILURE; } // Now invoke them as normal functions via their pointers std::cout << "sub(10, 5)=" << sub_func(10, 5) << "\n"; grt_func("World"); // Clean up dlclose(handle); return EXIT_SUCCESS; } ``` 在这个例子当中展示了怎样安全有效地载入外部共享对象以及如何正确地运用所提取出来的功能实体[^4]。 --- ### 示例代码总结 以上讨论涵盖了几个重要方面: - 如何正确定义适用于各种情况下的函数指针; - 解决因不同编程范式引发的兼容性挑战的最佳策略; - 提供了一套实用的技术手段帮助开发者顺利完成任务需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值