Передача данных между EXE / DLL - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть приложение DLL и EXE. DLL зарегистрирована в EXE. Тогда в EXE экземпляр класса A создается как shared_ptr. Затем этот экземпляр передается в DLL, и метод example этого экземпляра вызывается на стороне DLL.

class Result
{
//Some attributes e.g std::vector
}

class A
{
public:
    A(){}
    ~A(){}

    Result example(){
        Result r;
        //Fill data in r object....
        return r;
    }
}

Проблема в том, что когда example вызывается где-то в DLL:

void someDLLMethod()
{
    //a is a shared pointer of A class
    {
        Result r = a->example();
    }//PROBLEM IS HERE DURING DEALLOCATING Result OBJECT

    //some stuff...
}

Похоже, что проблема возникает при удалении r объекта. Я понимаю, когда я попытаюсь выделить часть памяти в EXE, а затем попытаться освободить эту память в DLL, тогда могут возникнуть проблемы с памятью, но в этом случае объект Result копируется из EXE в DLL. Кроме того, вектор, хранящийся в объекте Result, не содержит указателей, поэтому он должен быть глубокой копией вектора. Одним из решений является размещение Result объекта в DLL, передача его в качестве ссылки на вызываемый метод и заполнение всех необходимых данных, но я хочу получить копию в качестве результата. Почему эта проблема возникает? Как это можно исправить? EXE и DLL находятся в том же решении Visual Studio и должны быть скомпилированы с \ MT или \ MTd, и их невозможно изменить.

1 Ответ

0 голосов
/ 05 сентября 2018

Память для вектора выделяется в DLL и освобождается в exe, поскольку вектор, вероятно, использует в своем возвращении семантику перемещения (или даже просто RVO), которая просто перемещает указатель на выделенные внутренние компоненты. Поскольку вы используете статический ЭЛТ, это означает, что память распределяется с одним КРТ и освобождается с другим экземпляром, что приводит к ошибкам.

Короткая история - не делай этого. Экспонировать объекты C ++ через границы DLL - это плохо. Вы должны использовать интерфейс C или интерфейс, который предназначен для этого - например, WinRT.

Если вы решите выставлять объекты c ++ через интерфейс DLL, вы должны убедиться, что как EXE, так и DLL используют одну и ту же версию компилятора, и вы связываетесь с / MD. Если вы не можете использовать / MD, вы никогда не получите надежную работу.

Конечно, вы можете предварительно выделить вектор и заполнить его в вызове, но это только маскирует проблему, пока все неизбежно не изменится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...