这里说的继承有点像C++里的父类和子类,实际上是结构体类型的强制转换,最近看Linux内核源码时经常接触到这种方法,在这里就当作是一个简单的学习吧。
下面给出一个Demo,很简单,分别定义了一个father结构体和一个son结构体,father结构体里定义了2个整形变量,son结构体里的第一个成员是father结构体类型的变量,son里的另外2个成员也是整形变量,这样,son结构体就好像继承了father结构体,并增加了2个成员,代码如下:
2
3 //父结构体
4 struct father
5 {
6 int f1;
7 int f2;
8 };
9
10 //子结构体
11 struct son
12 {
13 //子结构体里定义一个父结构体变量,必须放在子结构体里的第一位
14 struct father fn;
15 //子结构体的扩展变量
16 int s1;
17 int s2;
18 };
19
20 void test(struct son *t)
21 {
22 //将子结构体指针强制转换成父结构体指针
23 struct father *f = (struct father *)t;
24 //打印原始值
25 printf("f->f1 = %d\n",f->f1);
26 printf("f->f2 = %d\n",f->f2);
27 //修改原始值
28 f->f1 = 30;
29 f->f2 = 40;
30 }
31
32 int main(void)
33 {
34 struct son s;
35 s.fn.f1 = 10;
36 s.fn.f2 = 20;
37
38 test(&s);
39 //打印修改后的值
40 printf("s.fn.f1 = %d\n",s.fn.f1);
41 printf("s.fn.f2 = %d\n",s.fn.f2);
42
43 return 0;
44 }
在这里,关键是把father类型的变量放在son结构体里的第一位。运行效果:
修改son结构体,使得father类型的变量不是放在son结构里的第一位,修改后如下:
2 struct son
3 {
4 //子结构体的扩展变量
5 int s1;
6 int s2;
7 struct father fn;
8 };
修改后的运行效果:
总结:
这种方法对于结构体的扩展很有用。
本文链接
.CLW文件
VC Class Wizard信息文件,存放了Class Wizard的信息。 ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下。有时候ClassWizard出问题,手工修改CLW文件可以解决。如果此文件不存在的话,每次用ClassWizard的时候会提示你是否重建
.NCB文件
无编译浏览文件(no compile browser),当自动完成功能出问题时可以删除此文件。build后会自动生成
.OPT文件
IDE的Option文件,工程关于开发环境的参数文件,如工具条位置等信息,保存工作空间的配置
.APS文件
资源文件的二进制版本,资源辅助文件,一般不用去管他
.clw文件
支持ClassWizard
.ncb文件
支持ClassView
.aps文件
支持ResourceView
.bsc文件
浏览器信息文件,用于浏览信息文件,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度
.dsp文件
DeveloperStudio Project,项目文件,文本格式,不过不熟悉的话不要手工修改
.dsw文件
DeveloperStudio Workspace,是工作区文件,其他特点和DSP差不多
.mak文件
外部的创建文件
.plg文件
建立日志文件,是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件),在Tools->Options里面有个选项可以控制这个文件的生成
.hpj文件
Help Project,是生成帮助文件的工程,用microsfot Help Compiler可以处理
.mdp文件
Microsoft DevStudio Project,是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式
.map文件
是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着
.pch文件
Pre-Compiled File,是预编译文件,可以加快编译速度,但是文件非常大
.pdb文件
Program Database,记录了程序有关的一些数据和调试信息,在调试的时候可能有用
.exp文件
只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息
本文链接
这段时间用到了dll的调用,这里总结下,也方便我以后使用。
一、生成dll(基于VS2010)
1、选择“Win32 Console Application”,建立工程;
2、向导中的“Application type”选择Dll,并在“Additional options”选项中勾选“Empty Project”;
3、点击“Finish”完成向导;
4、添加文件CallTest1.cpp,添加如下代码:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" _declspec(dllexport) int Max(int i1,int i2)
{
return (i1>i2)?i1:i2;
}
5、编译生成dll文件;
二、C++调用dll(基于VS2010)
1、选择“Win32 Console Application”,建立工程; 2、向导中的“Application type”选择“Console Application”,并在“Additional options”选项中勾选“Empty Project”; 3、点击“Finish”完成向导; 4、添加文件dllCall.cpp,添加如下代码:
#include <stdio.h>
#include <windows.h>
typedef int(*pMax)(int a,int b);
void main(void)
{
HINSTANCE hDLL;
pMax Max;
hDLL=LoadLibrary("dllTest1.dll");//加载动态链接库文件;
Max=(pMax)GetProcAddress(hDLL,"Max");
int a=Max(5,8);
printf("比较的结果为%d\n",a);
FreeLibrary(hDLL);//卸载文件;
getchar();
}
5、进入工程的属性选项,选择“Use Multi-Byte Character Set”;
6、编译程序,将dllTest1.dll文件copy到和dllCall.exe同一目录并运行;
三、c#调用dll(基于VS2010)
1、选择“Console Application”,建立dllCallCS工程;
2、在Program.cs文件中添加如下代码: using System.Runtime.InteropServices;
3、导入dll文件: [DllImport("dllTest1.dll")] public static extern int Max(int i1, int i2); 4、添加测试代码:
int ret = Max(1, 2);if (1 == ret)
Console.WriteLine("test");
else
Console.WriteLine("test2");
5、编译程序,将dllTest1.dll文件copy到和dllCallCS.exe同一目录并运行;
附Program.cs文件完整代码:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace dllCallCS
{
class Program
{
[DllImport("dllTest1.dll")]
public static extern int Max(int i1, int i2);
static void Main(string[] args)
{
int ret = Max(1, 2);
if (1 == ret)
Console.WriteLine("test");
else
Console.WriteLine("test2");
}
}
}
四、Python调用dll(基于Python2.7)
1、建立文件dllCall3.py文件,填充如下代码:
dll = CDLL("dllTest1.dll")
print dll.Max(1, 3)
2、将dllTest1.dll文件复制到该目录,运行程序;
好,就这些了,希望对你有帮助。
本文链接