qt默认的编程语言为C++语言。如果你用qt编译.c文件,会出现找不到C语言的默认头文件等错误(如:stdio.h等)。qt中不支持
extern "C"{}的这种写法,我前几天有一个C程序需要移植到Qt的工程中,本希望直接extern "C"就ok了,但发现qt4居然不支持这种写法。我的程序中用到了好几个linux系统头文件,是向串口发指令之类的程序,程序中用到了互斥锁并创建了一个线程。如果再用qt语言来写一遍的话我会挂掉的,所以没有办法,在网上找了半天,终于找到解决方法。
将.c文件编译为函数库的方式在qt下调用,这种方法貌似行得通,我就开始行动了。
下面的内容讲得比较多,比较全,比较适合初学者,是我在网上down的,给出了原网站的链接,最后给出了一个程序。经过自己整理好归纳如下:
需要说明的是:使用gcc可以将程序编译成动态库或者静态库的形式,它们在程序中的调用的方式也不尽相同,给出的程序中调用的是动态连接库。编译成动态的还是静态的根据自己的需要进行。如果原C程序编译的时候需要gcc的额外选项(如 gcc -lpthread -o hello hello.c)等,建议采用动态的形式。
1.什么是静态连接库,什么是动态链接库
静态链 ......
qt默认的编程语言为C++语言。如果你用qt编译.c文件,会出现找不到C语言的默认头文件等错误(如:stdio.h等)。qt中不支持
extern "C"{}的这种写法,我前几天有一个C程序需要移植到Qt的工程中,本希望直接extern "C"就ok了,但发现qt4居然不支持这种写法。我的程序中用到了好几个linux系统头文件,是向串口发指令之类的程序,程序中用到了互斥锁并创建了一个线程。如果再用qt语言来写一遍的话我会挂掉的,所以没有办法,在网上找了半天,终于找到解决方法。
将.c文件编译为函数库的方式在qt下调用,这种方法貌似行得通,我就开始行动了。
下面的内容讲得比较多,比较全,比较适合初学者,是我在网上down的,给出了原网站的链接,最后给出了一个程序。经过自己整理好归纳如下:
需要说明的是:使用gcc可以将程序编译成动态库或者静态库的形式,它们在程序中的调用的方式也不尽相同,给出的程序中调用的是动态连接库。编译成动态的还是静态的根据自己的需要进行。如果原C程序编译的时候需要gcc的额外选项(如 gcc -lpthread -o hello hello.c)等,建议采用动态的形式。
1.什么是静态连接库,什么是动态链接库
静态链 ......
/*
============================================================================
Name : test.c
Author : alf
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i;
char **ptr;
extern char **environ;
for (i = 0; i < argc; ++i) {
printf("argv[%d]: %s \n", i, argv[i]);
}
for (ptr = environ; *ptr != 0; ptr++) {
printf("%s \n", *ptr);
  ......
最近对基础知识进行了学习,发现以前很多东西都没有搞清楚
1. 编译的问题,头文件主要是定义
//////// add.c
int add(int a, int b)
{
return a + b;
}
///////// main.c
#include <stdio.h>
int add(int a, int b);
int main ()
{
printf("%d", add(1, 2));
return 0;
}
这是可以正确编译执行的,没有使用头文件
2. 继承的一些知识点
派生类向基类对象赋值时,给基类变量传入的数据是其本身基类的对应的数据 ......
最近对基础知识进行了学习,发现以前很多东西都没有搞清楚
1. 编译的问题,头文件主要是定义
//////// add.c
int add(int a, int b)
{
return a + b;
}
///////// main.c
#include <stdio.h>
int add(int a, int b);
int main ()
{
printf("%d", add(1, 2));
return 0;
}
这是可以正确编译执行的,没有使用头文件
2. 继承的一些知识点
派生类向基类对象赋值时,给基类变量传入的数据是其本身基类的对应的数据 ......
假设我们使用mysql_real_query执行了一条sql语句之后,返回值为非0值,大家都知道这是这条语句执行出错,但是我们想
了解地更详细点的话,究竟是什么原因导致了这个错误呢?这时候就得用上mysql提供的另外一个API:mysql_errno。
mysql_errno会提供最近一次调用的C API出错的信息(不见得每个API都会对这个errno进行设置,但是最常用的mysql_real_query是会的)。通过mysql_errno返回的错误码一般都有规则:比如属于区间[1000,2000)的错误是逻辑错误,比如键值冲突这种错误,这些错误是由服务器返回的;其他的比如[2000, 3000)的当然就不是逻辑错误了。
另外,如果想更加详细的信息,可以通过mysql_error函数返回一个错误信息的字符串 ......
假设我们使用mysql_real_query执行了一条sql语句之后,返回值为非0值,大家都知道这是这条语句执行出错,但是我们想
了解地更详细点的话,究竟是什么原因导致了这个错误呢?这时候就得用上mysql提供的另外一个API:mysql_errno。
mysql_errno会提供最近一次调用的C API出错的信息(不见得每个API都会对这个errno进行设置,但是最常用的mysql_real_query是会的)。通过mysql_errno返回的错误码一般都有规则:比如属于区间[1000,2000)的错误是逻辑错误,比如键值冲突这种错误,这些错误是由服务器返回的;其他的比如[2000, 3000)的当然就不是逻辑错误了。
另外,如果想更加详细的信息,可以通过mysql_error函数返回一个错误信息的字符串 ......
这是C的原程序
#include <stdio.h>
#include <regex.h>
int main(int argc, char** argv)
{
regex_t reg;
regmatch_t pm[10];
char *pattern;
char buf[50];
const size_t nmatch = 10;
pattern = argv[1];
int result = regcomp(®, pattern, REG_EXTENDED);
while( fgets(buf, sizeof(buf), stdin) )
{
int e = 0;
if ( e = strlen(buf) > 0 && buf[e-1] == '\n' )
buf[e-1] = 0;
result = regexec( ®, buf, nmatch, pm, REG_NOTBOL );
if ( result == REG_NOMATCH )
continue;
int i = 0;
for ( i = 0; i < nmatch && pm[i].rm_so != -1; ++i )
{
char c[50] ;
strncpy( c, buf + pm[i].rm_so, pm[i].rm_eo - pm[i].rm_so );
c[pm[i].rm_eo - pm[i].rm_so] = 0;
printf("%d,%d:%s\n", pm[i].rm_so, pm[i].rm_eo,c);
}
}
}
这是测试文件内容:
的rqyy rqyy
一ggll ggll
不gii gii
是jghu jghu
了bnh bnh是jghu jghu
我trnt trnt
他wbn wbn是jghu jghu
人wwww wwww
低点wqhk
低龄wq ......
这是C的原程序
#include <stdio.h>
#include <regex.h>
int main(int argc, char** argv)
{
regex_t reg;
regmatch_t pm[10];
char *pattern;
char buf[50];
const size_t nmatch = 10;
pattern = argv[1];
int result = regcomp(®, pattern, REG_EXTENDED);
while( fgets(buf, sizeof(buf), stdin) )
{
int e = 0;
if ( e = strlen(buf) > 0 && buf[e-1] == '\n' )
buf[e-1] = 0;
result = regexec( ®, buf, nmatch, pm, REG_NOTBOL );
if ( result == REG_NOMATCH )
continue;
int i = 0;
for ( i = 0; i < nmatch && pm[i].rm_so != -1; ++i )
{
char c[50] ;
strncpy( c, buf + pm[i].rm_so, pm[i].rm_eo - pm[i].rm_so );
c[pm[i].rm_eo - pm[i].rm_so] = 0;
printf("%d,%d:%s\n", pm[i].rm_so, pm[i].rm_eo,c);
}
}
}
这是测试文件内容:
的rqyy rqyy
一ggll ggll
不gii gii
是jghu jghu
了bnh bnh是jghu jghu
我trnt trnt
他wbn wbn是jghu jghu
人wwww wwww
低点wqhk
低龄wq ......
转C和汇编混合编程
.data是初始化的数据块。这些数据包括编译时被初始化的globle和static变量,也包括字符串。
连接器将OBJs及LIBs文件的.data结合成一个大的.data。local变量以放在一个线性的堆栈中,
不占.data和.bss的空间。和.text一样,数据块是以明文的形式存放在文件中的。无法防止对其物理的修改。
.bss区是存放未初始化全局和静态变量的。
在C和汇编混合编程的时候,存在C语言和汇编语言的变量以及函数的接口问题。
在C程序中定义的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中定义的函数,编译后在函数名前也带了一个下划线。例如:
extern int num就会变成 .bss _num, 1
extern float nums[5]就会变成.bss _nums, 5
extern void func ( )就会变成 _func,
函数声明: C中在函数前加extern声明此函数为外部函数,在汇编中要声明函数名为全局变量,如:
extern void delay(void) ; /*in C*/
globl delay ; in asm
_delay: ; delay function begins
(1) 汇编程序中访问c程序中的变量和函数。
在汇编程序中,用_XX就可以访问C中的变 ......
转C和汇编混合编程
.data是初始化的数据块。这些数据包括编译时被初始化的globle和static变量,也包括字符串。
连接器将OBJs及LIBs文件的.data结合成一个大的.data。local变量以放在一个线性的堆栈中,
不占.data和.bss的空间。和.text一样,数据块是以明文的形式存放在文件中的。无法防止对其物理的修改。
.bss区是存放未初始化全局和静态变量的。
在C和汇编混合编程的时候,存在C语言和汇编语言的变量以及函数的接口问题。
在C程序中定义的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中定义的函数,编译后在函数名前也带了一个下划线。例如:
extern int num就会变成 .bss _num, 1
extern float nums[5]就会变成.bss _nums, 5
extern void func ( )就会变成 _func,
函数声明: C中在函数前加extern声明此函数为外部函数,在汇编中要声明函数名为全局变量,如:
extern void delay(void) ; /*in C*/
globl delay ; in asm
_delay: ; delay function begins
(1) 汇编程序中访问c程序中的变量和函数。
在汇编程序中,用_XX就可以访问C中的变 ......