2016-06-30 4 views
1

Мне поручена задача создания DLL с множеством функций. Конкретная реализация функций на самом деле довольно проста, но общая (или лучше: начальная) настройка дает мне головную боль, и я еще не мог ее понять. Так вот два (из многих) функции Я должен реализовать:Win32 DLL/Справочное хранилище

long initClient(long* client, char* a = "", char* b = ""); 
long clientSet(int client, const char* a, const char* b); 

Первой настройку функции будет клиент (может быть 0..n, каждый клиент имеет внутренние данные состояния), так что как-то необходимо будет отслеживать данные, связанные с клиентом, внутри страны. Теперь, когда я вызываю clientSet (вторая функция), мне нужно передать целочисленное значение (long * client), которое я получаю от initClient к функции, чтобы он мог идентифицировать правильную структуру данных клиента и изменять эти данные.

Актуальный вопрос: как это сделать правильно?

Моим текущим решением было бы иметь внутренний список клиентов с их ассоциированными данными/идентификатором и использовать malloc/free всякий раз, когда клиент будет добавлен или удален. Тем не менее, я чувствую, что это не чистое решение или что его можно решить лучше.

Ваша помощь очень ценится.

EDIT: После переосмысления этого может быть, что первый параметр clientSet на самом деле является указателем, который я получаю от initClient (первый параметр)? Если это так, initClient должен был бы только malloc некоторой памяти и заполнить это данными. Все остальные вызовы будут ссылаться только на эту область памяти. Тем не менее, мне очень сложно использовать разные типы данных для одного и того же указателя (я получаю указатель на длинный, который затем мне нужно интерпретировать как int - я понимаю, что оба они имеют 4 байта на Win32). Я здесь?

EDIT # 2: К сожалению, мне не разрешено каким-либо образом изменять интерфейс.

EDIT # 3: После того, как более думать об этой проблеме, может быть, это то, что я на самом деле после того, как:

intptr_t my_ptr; 

long initClient(intptr_t* client, char* a, char* b); 
long clientSet(intptr_t client, char* a, char* b); 

initClient (& my_ptr, "A", "B") в основном (я потребуется чтобы увидеть, как это сделать де ссылок правильно) сделать

*client = (intptr_t)malloc(sizeof(myDataStructure)); 

Теперь я мог бы назвать

clientSet(my_ptr, "X", "Y"); 

Означает ли это, что это может быть то, что я должен делать?

+2

Предлагаю вам 2 вещи: 1) опубликовать код с вашим вопросом, 2) разработать интерфейс со всеми связанными с клиентом методами, сделать класс в dll, реализующий эти методы, и EXPORT только одной функцией, возвращающей этот метод, таким образом: __declspec (dllexport) client_interface * GetClientManager(); –

+0

@ GerardoSánchez: К сожалению, мне не разрешено изменять интерфейс, я также добавил некоторые пояснения. Что касается кода: у меня его пока нет. Я хотел бы понять, как это сделать «правильно», прежде чем я даже начну взламывать что-то вместе. –

+1

вы экспортируете функции C, но вы можете реализовать их с помощью C++. в этом случае вы можете использовать все необходимые контейнеры (std :: map) для хранения ваших данных для каждого клиента. – AnatolyS

ответ

2

Вам нужны функции экспорта C, но вы можете реализовать их с помощью C++. В этом случае вы можете использовать все необходимые контейнеры и типы данных (std :: map, std :: string) для хранения данных для каждого клиента. Как вы можете видеть, что нет какой-либо таНос:

struct client { 
    std::string a; 
    std::string b; 
}; 

std::map<long, client> clients; 

extern "C" { 
    long initClient(long* clientid, char* a = "", char* b = "") { 
    // if you need generate clientid you can use static atomic long 
    static std::atomic_long id(0); 
    clients[*clientid = ++id] = client{ a, b }; 
    return *clientid; 
    } 
    long clientSet(int clientid, const char* a, const char* b) { 
    clients[clientid] = client{ a, b }; 
    return clientid; 
    } 
} 
0

После тщательного рассмотрения (и некоторые дискуссии), мы решили пойти следующим образом:

  • initClient создает malloc'ed область памяти и возвращает указатель на этот экземпляр (который затем используется как int, который может быть проблемой в будущем, но который в настоящее время обсуждается)
  • Все функции работают над этой областью malloc'ed
  • добавлена ​​дополнительная функция endClient, которая свободная зарезервированная память пространство.

По-видимому, настоящая проблема заключается в использовании int в качестве хранилища для указателя.

Смежные вопросы