0

I am getting an undefined reference to 'mgmt_new_default()' error while trying to merge some C code into a C++ project.

I am trying to set a property of my class in its constructor. This class is called 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 (with faulty code that causes error)

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

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

The function mgmt_new_default(void) is from a file called mgmt.c, below are both header and body.

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 (Just conflicting 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;
}

What I don't understand is where this error could come from? I feel like I need a second pair of eyes for this. I think I correctly implemented any header guards necessary, but this just stumps me.

Please note that I am not using the BlueZ source code directly, but was experimenting by picking out some files I wanted and "merged" them into a C++ Project. I merged the mgmt.c and mgmt.h files "as is" without making changes, except for the header guard.

Zimano
  • 1,870
  • 2
  • 23
  • 41

1 Answers1

3

Your header file have to use extern "C" for functions defined in C file, whenever compiled by C++ compiler. The common idiom is following to be used in .h file

#ifdef __cplusplus
extern "C" {
#endif
// your functions declarations
#ifdef __cplusplus
}
#endif
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • The right thing to do was to wrap `#include "bluetooth/src/mgmt.h"` inside of an `extern "C"` block. However, your method seems more commonly used. Could you please elaborate a bit more? I can accept this answer if you tell me what header file this has to be applied to! – Zimano Dec 09 '15 at 09:47
  • The one which is declaring your C functions. – SergeyA Dec 09 '15 at 17:06