extern

C/C++混合编程编译问题

匿名 (未验证) 提交于 2019-12-02 23:52:01
情景1: C程序里面调用C++的类的接口 Makefile为: 如果用g++编译的话,没问题直接过。如果企图用gcc去编译的话,报错 可以看到是个链接错误,这是由于gcc在链接阶段企图把main.c中的函数和libpal_queue进行链接时出错,因为libpal_queue是pal_queue.cpp 编出来的,gcc碰到.cpp文件也是会按照C++的方式去处理的,因此编出来的函数名是修饰过的,而main.o在链接的时候还傻乎乎的按照c的方式去 找函数,所以就出错了。而使用g++则可以同时处理C和C++,因此链接的时候也不会有什么问题。 所以结论就是,C调用C++(main.c中调用C++的一个类的接口)的情况,使用g++去编译链接。(实际上,“编译阶段,g++会调用gcc,对于c++ 代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接, 所以通常用g++来完成链接,为了统一起见,干脆编译/链接统统用g++ 了,这就给人一种错觉,好像cpp程序只能用 g++ 似的” ) g++ 会自动进行 C++ 标准库的连接;用 gcc 连接 C++ 程序也可以,但是需要人为指定连接 C++ 标准库,否则就会出现undefined reference to `__gxx_personality_v/0' 之类的错误,gcc 情景2:C++中调用C(UNITTEST

C/C++中extern关键字详解

僤鯓⒐⒋嵵緔 提交于 2019-12-02 23:51:35
转自 https://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释 :extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。 也就是说extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,这要看编译器的"脾气"了(不同的编译器采用的方法不一样),为什么这么做呢,因为C++支持函数的重载啊,在这里不去过多的论述这个问题,如果你有兴趣可以去网上搜索,相信你可以得到满意的解释! 第二,当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块活其他模块中使用,记住它是一个声明不是定义!也就是说B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段

.NET 互操作

匿名 (未验证) 提交于 2019-12-02 23:47:01
.NET 互操作   首先推荐一本书 《精通.NET 互操作》 ,这本书是目前中文资料里讲 互操作最详尽的书了。   做系统集成项目的同学应该都和设备打过交道(如视频设备:海康、大华等),在大多数情况下这些设备厂商会给系统集成厂商开发协议(dll 类库、 函数定义的头文件、测试程序、调用流程),这些协议的dll 大都用C++开发的,那么我们用C#集成,就得用 P/Invoke 技术(.NET 互操作的一种) 一、P/Invoke 简单例子   P/Invoke 说白了,就是你调用协议dll 的函数,传入正确的参数(注意C++与C#的数据类型转换)   例子: 1 using System . Runtime . InteropServices ; 2 3 class App 4 { 5 [ DllImport ( "msvcrt.dll" )] 6 static extern int puts ( string msg ); 7 8 [ DllImport ( "msvcrt.dll" )] 9 static extern int _flushall (); 10 11 static void Main () 12 { 13 puts ( "Hello World" ); 14 _flushall (); 15 CreateMsgWindow (); 16 } 17 18 19 [

[C/C++] C++声明和定义的区别

匿名 (未验证) 提交于 2019-12-02 23:36:01
・变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。 ・变量声明:用于向程序表明变量的类型和名字。 ・定义也是声明:当定义变量时我们声明了它的类型和名字。 ・extern关键字:通过使用extern关键字声明变量名而不定义它。 1. 定义也是声明,extern声明不是定义,即不分配存储空间 。extern告诉编译器变量在其他地方定义了。 1 extern int i; //声明,不是定义 2 int i; //声明,也是定义 2. 如果声明有初始化式,就被当作定义,即使前面加了extern 。只有当extern声明位于函数外部时,才可以被初始化。 1 extern double pi=3.1416; //定义 3. 函数 的声明和定义区别比较简单, 带有{ }的就是定义,否则就是声明 。 1 extern double max(double d1,double d2); //声明,此时extern可去掉 程序设计风格: 1. 不要把变量定义放入.h文件,这样容易导致重复定义错误。 2. 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。 3. 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。 总结: 1.变量在使用前就要被定义或者声明。 2.在一个程序中,变量只能定义一次,却可以声明多次。 3

c语言中static 用法

匿名 (未验证) 提交于 2019-12-02 23:35:02
static在c里面可以用来修饰变量,也可以用来修饰函数。 先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不是堆,不要弄混。 int a ; int main() { } a是全局变量,b是栈变量,c是堆变量。 static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。 static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就结束了。但加入static修饰之后,变量已经不再存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 static对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。 文件a.c { } { } 上面的全局i变量和init()函数只能用在a.c文件中,全局变量sum的作用域只在callme里。变量j和函数callme()的全局限扩充到整个工程文件。所以可以在下面的b.c中用extern关键字调用。extern告诉编译器这个变量或者函数在其他文件里已经被定义了。

C#中DllImport用法和路径问题

匿名 (未验证) 提交于 2019-12-02 23:26:52
原文: C#中DllImport用法和路径问题 DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。 DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。 DllImport的定义如下: [AttributeUsage(AttributeTargets.Method)]   public class DllImportAttribute: System.Attribute   {    public DllImportAttribute(string dllName) {…} //定位参数为dllName    public CallingConvention CallingConvention; //入口点调用约定    public CharSet CharSet; //入口点采用的字符接    public string EntryPoint; //入口点名称    public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false    public bool PreserveSig; //方法的签名是被保留还是被转换    public bool SetLastError; /

extern keyword usage

荒凉一梦 提交于 2019-12-02 22:13:22
I have three programs in which I am using extern keyword. I am not able to understand the result. Below are three examples: Example 1: I was expecting that below code will give compilation error that multiple declaration of k . But it works fine? int k; //works fine extern int k = 10; void main() { cout<<k<<endl; getchar(); } Example 2: When I am trying to initialize "k" in above example compiler gives error. Why? int k = 20; //error extern int k = 10; void main() { cout<<k<<endl; getchar(); } Example 3: In this example I changed the order of definitions mentioned in example 1. When I compile

c# 多种方法调整屏幕亮度

匿名 (未验证) 提交于 2019-12-02 22:06:11
https://github.com/CHNMaxGor/AjustScreenBrightness 方法一: 使用网上常说的 Gdi32.dll 下的 SetDeviceGammaRamp (修改系统Gamma) DllImport("gdi32.dll")] public static extern bool GetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp); [DllImport("gdi32.dll")] public static extern bool SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp); 方法二: 使用MSDN上的 dxva2.dll SetMonitorBrightness 1 [DllImport("dxva2.dll")] 2 public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors); 3 4 [DllImport("dxva2.dll")] 5 public static extern bool GetPhysicalMonitorsFromHMONITOR(IntPtr

利用IME完成接收输入法输入功能.

匿名 (未验证) 提交于 2019-12-02 22:06:11
调用windows的 imm32.dll 完成窗体接收输入法功能. 代码如下    /// <summary> /// 输入法组件 /// </summary> class ImeComponent { #region Event /// <summary> /// 输入文本事件 /// </summary> public delegate void InputTextEvent(string text); /// <summary> /// 输入文本事件 /// </summary> public event InputTextEvent InputText; #endregion #region PrivateField IntPtr hIMC; IntPtr handle; private const int WM_IME_SETCONTEXT = 0x0281; private const int WM_IME_CHAR = 0x0286; private const int WM_CHAR = 0x0102; private const int WM_IME_COMPOSITION = 0x010F; private const int GCS_RESULTSTR = 0x0800; private const int GCS_COMPSTR = 0x0008;

Linux链接库三(C跟C++之间动态库的相互调用)

匿名 (未验证) 提交于 2019-12-02 21:56:30
http://www.cppblog.com/wolf/articles/74928.html http://www.cppblog.com/wolf/articles/77828.html http://www.jb51.net/article/34990.htm C和C++之间库的互相调用 extern "C"的理解: 很多人认为"C"表示的C语言,实际并非如此,"C"表示的是一种链接约定,只是因C和C++语言之间的密切关系而在它们之间更多的应用而已。实际上Fortran和汇编语言也常常使用,因为它们也正好符合C实现的约定。 extern "C"指令描述的是一种链接约定,它并不影响调用函数的定义,即时做了该声明,对函数类型的检查和参数转换仍要遵循C++的标准,而不是C。 2.extern "C"的作用: 不同的语言链接性是不同的,那么也决定了它们编译后的链接符号的不同,比如一个函数void fun(double d),C语言会把它编译成类似_fun这样的符号,C链接器只要找到该函数符号就可以链接成功,它假设参数类型信息是正确的。而C++会把这个函数编译成类似_fun_double或_xxx_funDxxx这样的符号,在符号上增加了类型信息,这也是C++可以实现重载的原因。 那么,对于用C编译器编译成的库,用C++直接链接势必会出现不能识别符号的问题,是的,需要extern "C