C++与C混编

本案例通过实现一个简单的UDP服务器来说明C++与C的混合编程问题

C代码

通过C代码来对UDP服务器的创建,监听进行封装

udp.c文件

#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h> #define MAXLINE 512 static int server = -1;
static struct sockaddr_in addr_server;
static char server_buff[MAXLINE]; void create_server(int port) {
if (server == -1) {
server = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&addr_server, sizeof(addr_server));
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(port);
addr_server.sin_addr.s_addr = htonl(INADDR_ANY);
bind(server, (struct sockaddr*)&addr_server, sizeof(addr_server));
}
}
const char* socket_recv() {
bzero(server_buff, MAXLINE);
recvfrom(server, server_buff, MAXLINE, 0, NULL, NULL);
return server_buff;
}

create_server(int)是用来创建一个udp服务器,而socket_recv() 则是从端口中读取数据并将数据返回

udp.h文件

#ifndef UDP_H
#define UDP_H #ifdef __cplusplus
extern "C" { //如果被C++文件引用
#endif void create_server(int);
const char* socket_recv(); #ifdef __cplusplus
}
#endif #endif

在该文件中对封装的接口进行声明,以方便其它人调用。该头文件即可被C程序引用又可以被C++程序引用。如果在C++文件中引入了C文件中的函数,则必须要用extern "C" {} 将函数包起来。因为使用C++编译器 在编译时会自动添加__cplusplus 这个宏,所以可以在头文件中判断出该头文件是被C++文件引用了,还是被C文件引用了。

C++代码

udp_server.h文件

声明一个类UdpServer

#include <iostream>
namespace xdysite {
class UdpServer {
public:
const char* recevice();
static UdpServer* newInstance(int port);
void close();
private:
UdpServer();
~UdpServer();
private:
static UdpServer* single;
int port;
};
}

该类采用单例模式,只能通过newInstance来创建对象,通过recevice()就收数据,通过close()关闭服务器并释放资源

udp_server.cpp文件

实现类UdpServer

#include "udp_server.h"
#include "udp.h" xdysite::UdpServer* xdysite::UdpServer::single = NULL; xdysite::UdpServer::UdpServer() { } xdysite::UdpServer* xdysite::UdpServer::newInstance(int port) {
if (single == NULL) {
single = new UdpServer();
single->port = port;
create_server(port);
return single;
}
} const char* xdysite::UdpServer::recevice() {
return socket_recv();
} xdysite::UdpServer::~UdpServer() { } void xdysite::UdpServer::close() {
if (single != NULL) {
delete single;
single = NULL;
}
}

主程序

#include <iostream>
#include "udp_server.h"
using namespace std;
using namespace xdysite; int main(int argc, char* argv[]) {
UdpServer* udpServer = UdpServer::newInstance(8080);
for(;;) {
cout << udpServer->recevice() << endl;
}
}

在主程序中创建了一个Udp服务器,并从该服务器中不断读取数据输出

编译

编译的时候有两种编译方案,推荐使用第二种

方案一

通过GCC编译器将udp.c编译称udp.o

gcc -c udp.c -o udp.o

通过G++编译器将udp_server.cpp, man.cpp编译成.o文件

g++  -c udp_server.cpp -o udp_server.o
g++ -c main.cpp -o main.o

生成可执行程序

g++ main.o udp_server.o udp.o -o myudp

方案二

通过GCC将udp.c编译成动态库libudp.so

gcc -c -fPIC -shared udp.c -o libudp.so

通过G++编译器将udp_server.cpp, man.cpp编译成.o文件

g++  -c udp_server.cpp -o udp_server.o
g++ -c main.cpp -o main.o

生成可执行程序(-L指定动态库目录, -l指定动态库名)

g++ main.o udp_server.o -o myudp -L. -ludp

附录

方案二的makefile

CC=g++
SRCS=main.cpp \
udp_server.cpp
OBJS=$(SRCS:.cpp=.o)
OBJS+=udp.o
EXEC=myudp
start:$(OBJS)
$(CC) $(OBJS) -o $(EXEC) -L -ludp
.cpp.o:
$(CC) -c $< -o $@ clean:
rm -fr $(OBJS)

客户端程序

用java实现

public class DaytimeUDPClient {

	private final static int PORT = 8080;
private static final String HOSTNAME = "www.xdysite.cn"; public static void main(String[] args) {
// 传入0表示让操作系统分配一个端口号
try (DatagramSocket socket = new DatagramSocket(0)) {
socket.setSoTimeout(10000);
InetAddress host = InetAddress.getByName(HOSTNAME);
// 指定包要发送的目的地
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String str = sc.nextLine();
byte[] data = str.getBytes("UTF-8");
DatagramPacket request = new DatagramPacket(data, data.length,
host, PORT);
socket.send(request);
} } catch (IOException e) {
e.printStackTrace();
}
}
}

C++与C混编的更多相关文章

  1. Swift和Objective-C混编注意事项

    前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲 ...

  2. iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较

        即使你尽量用Swift编写iOS程序,难免会遇到部分算法是用C++语言编写的.那你只能去问问”度娘“或“狗哥”怎么用Swift调用C++算法.   一,C,C++, Objective-C,S ...

  3. IOS --- OC与Swift混编

    swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. ...

  4. Processing与Java混编初探

    Processing其实是由Java开发出的轻量级JAVA开发语言,主要用于做原型,有setup.draw两个主接口和几个消息相应接口 Processing和Java混编很简单...在Java中引入外 ...

  5. obeject-c 与 swift 混编

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px ".PingFang SC"; color: #454545 } p.p2 ...

  6. iOS开发--Swift 如何完成工程中Swift和OC的混编桥接(Cocoapods同样适用)

    由于SDK现在大部分都是OC版本, 所以假如你是一名主要以Swift语言进行开发的开发者, 就要面临如何让OC和Swift兼容在一个工程中, 如果你没有进行过这样的操作, 会感觉异常的茫然, 不用担心 ...

  7. iOS之 C++与oc混编

    声明:本文只是随笔,自己做个笔记方便以后查阅如要转载,注明出处.谢谢! 2016年第一篇随笔!!! 由于最近要搞一个项目用到c++的一些api所以要混编,于是就记录下这个过程中的一些细节上的东西! O ...

  8. swift混编oc碰到的问题

    在swift中混编苹果官方的Reachability OC文件. 因为swift工程的target是生成framework而非app,framework中调用oc与app中使用桥接文件还不一样,参考: ...

  9. swift objective-及c语言 混编

    在xocde6出来我们大部分代码都是用objective-c写的(部分C/C++),现在出生来了一个新的语言叫swift,那么如何既能使用我们之前的代码,还可以使用新语言呢, 本文就此做一下说明. 关 ...

  10. [ios][swift]swift混编

    http://blog.csdn.net/iflychenyang/article/details/8876542(如何在Objective-C的头文件引用C++的头文件) 1.将.m文件扩展名改为. ...

随机推荐

  1. leetcode 153: Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  2. iOS 关于 UIKit 专栏应该写在最前面的话

    iOS 关于 UIKit 应该写在最前面的话 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协 ...

  3. Fragment之间传数据

    1.用bundle存Bundle bundle = new Bundle();bundle.putString("cid1", classList.get(i).getId()); ...

  4. centos7上开启路由转发

    CentOS7 开启路由转发 2018-03-27   09:18:14 1.临时开启,(写入内存,在内存中开启) echo "1" > /proc/sys/net/ipv4 ...

  5. 《从零开始学Swift》学习笔记(Day 71)——Swift与C/C++混合编程之数据类型映射

    原创文章,欢迎转载.转载请注明:关东升的博客 如果引入必要的头文件,在Objective-C语言中可以使用C数据类型.而在Swift语言中是不能直接使用C数据类型,苹果公司为Swift语言提供与C语言 ...

  6. nvm-windows 安装后,node 命令报错

    下载地址: https://github.com/coreybutler/nvm-windows/releases 我是点下面这个直接安装的: 配置文件,我都是习惯在软件目录下建个 files 文件夹 ...

  7. centos免密登录

    本文是为了docker-machine增加现有虚拟机服务器为节点而做 docker-machine create -d generic --generic-ip-address=192.168.102 ...

  8. 【转载】Java并发编程:volatile关键字解析

    http://www.cnblogs.com/dolphin0520/p/3920373.html

  9. Whether to hide the cookie from JavaScript

    w禁用js访问特定cookie. https://codeigniter.com/userguide3/helpers/cookie_helper.html $this->load->he ...

  10. Apache 2.4 配置多个虚拟主机的问题

    以前一直用Apache2.2的版本,最近升级到了2.4的版本,尝尝新版本嘛. 不过遇到了几个问题,一个就是配置了多个virtualhost,虽然没有报错,不过除了第一可以正常访问外,其他的都存在403 ...