2015-12-08 74 views
0

我试图将一些C代码合并到C++项目时出现undefined reference to 'mgmt_new_default()'错误。未定义的引用功能使用混合的C和C++

我想在我的类的构造函数中设置属性。此类称为SocketManager

socketmanager.h

#ifndef SOCKETMANAGER_H 
#define SOCKETMANAGER_H 
#include "bluetooth/src/mgmt.h" 
class SocketManager 
{ 
public: 
SocketManager(); 

struct mgmt *management; 

//MGMT-related methods 
void Initialize(); 
void StartDiscovery(); 
}; 

#endif // SOCKETMANAGER_H 

socketmanager.c(具有可能导致错误错误代码)

#include "socketmanager.h" 
#include "bluetooth/src/mgmt.h" 

SocketManager::SocketManager() 
{ 
    this->management = mgmt_new_default(); 
} 

功能mgmt_new_default(void)是从一个文件名为mgmt.c,下面是标题和正文。

mgmt.h

#ifndef MGMT2_H 
#define MGMT2_H 

#include <stdbool.h> 
#include <stdint.h> 

#define MGMT_VERSION(v, r) (((v) << 16) + (r)) 

typedef void (*mgmt_destroy_func_t)(void *user_data); 

struct mgmt; 

struct mgmt *mgmt_new(int fd); 
struct mgmt *mgmt_new_default(void); 

struct mgmt *mgmt_ref(struct mgmt *mgmt); 
void mgmt_unref(struct mgmt *mgmt); 

typedef void (*mgmt_debug_func_t)(const char *str, void *user_data); 

bool mgmt_set_debug(struct mgmt *mgmt, mgmt_debug_func_t callback, 
      void *user_data, mgmt_destroy_func_t destroy); 

bool mgmt_set_close_on_unref(struct mgmt *mgmt, bool do_close); 

typedef void (*mgmt_request_func_t)(uint8_t status, uint16_t length, 
       const void *param, void *user_data); 

unsigned int mgmt_send(struct mgmt *mgmt, uint16_t opcode, uint16_t index, 
       uint16_t length, const void *param, 
       mgmt_request_func_t callback, 
       void *user_data, mgmt_destroy_func_t destroy); 
unsigned int mgmt_send_nowait(struct mgmt *mgmt, uint16_t opcode,  uint16_t index, 
       uint16_t length, const void *param, 
       mgmt_request_func_t callback, 
       void *user_data, mgmt_destroy_func_t destroy); 
unsigned int mgmt_reply(struct mgmt *mgmt, uint16_t opcode, uint16_t index, 
       uint16_t length, const void *param, 
       mgmt_request_func_t callback, 
       void *user_data, mgmt_destroy_func_t destroy); 
bool mgmt_cancel(struct mgmt *mgmt, unsigned int id); 
bool mgmt_cancel_index(struct mgmt *mgmt, uint16_t index); 
bool mgmt_cancel_all(struct mgmt *mgmt); 

typedef void (*mgmt_notify_func_t)(uint16_t index, uint16_t length, 
       const void *param, void *user_data); 

unsigned int mgmt_register(struct mgmt *mgmt, uint16_t event, uint16_t index, 
      mgmt_notify_func_t callback, 
      void *user_data, mgmt_destroy_func_t destroy); 
bool mgmt_unregister(struct mgmt *mgmt, unsigned int id); 
bool mgmt_unregister_index(struct mgmt *mgmt, uint16_t index); 
bool mgmt_unregister_all(struct mgmt *mgmt); 

#endif // MGMT2_H 

mgmt.c(只是冲突的mgmt_new_default())

struct mgmt *mgmt_new_default(void) 
{ 
struct mgmt *mgmt; 
union { 
    struct sockaddr common; 
    struct sockaddr_hci hci; 
} addr; 
int fd; 

fd = socket(PF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 
          BTPROTO_HCI); 
if (fd < 0) 
    return NULL; 

memset(&addr, 0, sizeof(addr)); 
addr.hci.hci_family = AF_BLUETOOTH; 
addr.hci.hci_dev = HCI_DEV_NONE; 
addr.hci.hci_channel = HCI_CHANNEL_CONTROL; 

if (bind(fd, &addr.common, sizeof(addr.hci)) < 0) { 
    close(fd); 
    return NULL; 
} 

mgmt = mgmt_new(fd); 
if (!mgmt) { 
    close(fd); 
    return NULL; 
} 

mgmt->close_on_unref = true; 

return mgmt; 
} 

我不明白的是,其中该错误可能是从哪里来的?我觉得我需要第二双眼睛。我认为我正确实施了任何必要的标头卫兵,但这只是让我难过。

请注意,我并未直接使用BlueZ源代码,而是通过挑选一些我想要的文件并将它们“合并”为一个C++项目来进行试验。我将“原样”合并了mgmt.cmgmt.h文件,但没有进行任何更改,除了标头警卫。

+0

使用看一看[这](http://stackoverflow.com/questions/1041866/in-c-source-what-is-the- extern-c) –

+0

你是如何编译它的? – NathanOliver

回答

2

无论何时由C++编译器编译,头文件都必须使用extern“C”来定义C文件中定义的函数。常见的成语是继在.h文件中

#ifdef __cplusplus 
extern "C" { 
#endif 
// your functions declarations 
#ifdef __cplusplus 
} 
#endif 
+0

正确的做法是在'extern“C”块中包装#include“bluetooth/src/mgmt.h”。但是,您的方法似乎更常用。你能否详细说明一下?我可以接受这个答案,如果你告诉我这个头文件必须应用于! – Zimano

+0

这是宣布你的C函数。 – SergeyA