Обертывание управляется с помощью неуправляемого интерфейса - PullRequest
5 голосов
/ 11 сентября 2011

У меня есть неуправляемая библиотека, отображающая некоторые интерфейсы.Пользователи могут реализовывать интерфейсы и вставлять их в библиотеку с помощью их собственной реализации.

Я хотел бы предоставить управляемую оболочку для этой библиотеки.Свернуть неуправляемый интерфейс с управляемым легко.Но в моем случае я хотел бы поддержать пользовательские реализации различных интерфейсов, что означает, что мне нужно взять управляемую реализацию интерфейса и обернуть ее, используя ее неуправляемый аналог, прежде чем я отправлю его в глубины неуправляемой части библиотеки.

Я пробовал что-то вроде:

class UnmanagedWrapper {
DoSomething() {m_clr.DoSomething();}
IManaged^ m_clr;
}

Но я не могу управлять членами в неуправляемом классе, справедливо заявил компилятор.

Могу ли я сделать что-нибудь элегантное здесь?

Ответы [ 3 ]

0 голосов
/ 26 августа 2015

Может быть gcroot <> - это то, что вы хотите:

class UnmanagedWrapper {
    DoSomething() {m_clr.DoSomething();}
    gcroot<IManaged^> m_clr;
}
0 голосов
/ 19 августа 2017

Вам необходимо импортировать вашу неуправляемую DLL в ваше приложение C # .Net.Мой пример возвращает указатель на структуру, но вы можете указать любой другой тип возврата, который нужен вашему приложению.Обязательно используйте dumpbin.exe / EXPORTS, чтобы получить всю функцию / имя EntryPoint из dll.Вот весь мой класс:

using System;
using System.Runtime.InteropServices;

namespace aviationLib
{
    public struct MAGtype_GeoMagneticElements
    {
        public double Decl; /* 1. Angle between the magnetic field vector and true north, positive east*/
        public double Incl; /*2. Angle between the magnetic field vector and the horizontal plane, positive down*/
        public double F; /*3. Magnetic Field Strength*/
        public double H; /*4. Horizontal Magnetic Field Strength*/
        public double X; /*5. Northern component of the magnetic field vector*/
        public double Y; /*6. Eastern component of the magnetic field vector*/
        public double Z; /*7. Downward component of the magnetic field vector*/
        public double GV; /*8. The Grid Variation*/
        public double Decldot; /*9. Yearly Rate of change in declination*/
        public double Incldot; /*10. Yearly Rate of change in inclination*/
        public double Fdot; /*11. Yearly rate of change in Magnetic field strength*/
        public double Hdot; /*12. Yearly rate of change in horizontal field strength*/
        public double Xdot; /*13. Yearly rate of change in the northern component*/
        public double Ydot; /*14. Yearly rate of change in the eastern component*/
        public double Zdot; /*15. Yearly rate of change in the downward component*/
        public double GVdot; /*16. Yearly rate of change in grid variation*/
    };

    public class Declination
    {
        [DllImport("wmm.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "?GeoMagneticElements@@YAPAUMAGtype_GeoMagneticElements@@MHHMMM@Z")]
        public static extern IntPtr GeoMagneticElements(float sdate, int igdgc, int units, float alt, float latitude, float longitude);

        public MAGtype_GeoMagneticElements e;

        public MAGtype_GeoMagneticElements MagDeclination(float decimalLat, float decimalLon)
        {

           try
            {
                String d = DateTime.Now.Year.ToString("D4") + '.' + DateTime.Now.Day.ToString("D1");
                IntPtr pnt = GeoMagneticElements((float)Convert.ToDouble(d), 1, 3, 3000.0f, decimalLat, decimalLon);
                e = Marshal.PtrToStructure<MAGtype_GeoMagneticElements>(pnt);
            }
            catch (System.EntryPointNotFoundException se)
            {
                Console.WriteLine(se.Message);
            }

            return e;
        }
    }
}

Настройка слова должна быть одинаковой как для управляемой, так и для неуправляемой, поэтому, если dll 32-битная, то и .NET должна быть такой же.

0 голосов
/ 03 февраля 2012

Вот некоторая связанная информация для обходных путей, когда одна библиотека неуправляема, и управляемый язык использует эти библиотеки.

Контекст этой информации является способом использования GoogleTest в Visual Studio:

Начало работы с Google C ++ Testing Framework

Важное замечание для пользователей Visual C ++ Если вы поместите свои тесты в библиотека и ваша функция main () находится в другой библиотеке или в вашем .exe файл, эти тесты не будут выполняться. Причиной является ошибка в Visual C ++. Когда вы определяете свои тесты, Google Test создает определенные статические объекты для их регистрации. На эти объекты не ссылаются из в другом месте, но их конструкторы все еще должны работать. когда Компоновщик Visual C ++ видит, что ничего из библиотеки не указано в других местах он выбрасывает библиотеку. Вы должны сослаться на библиотека с тестами из вашей основной программы, чтобы компоновщик не отбрасывая это. Вот как это сделать. Где-то в вашей библиотеке код объявить функцию:

__declspec (dllexport) int PullInMyLibrary() { return 0; }

Если вы поместите свои тесты в статическую библиотеку (не DLL), тогда __declspec (dllexport) будет

не требуется. Теперь, в вашей основной программе, напишите код, который вызывает эта функция:

   int PullInMyLibrary(); 
   static int dummy = PullInMyLibrary();

Это будет сохраняйте ссылки на свои тесты и заставляйте их регистрироваться на ввод в эксплуатацию.

Кроме того, если вы определяете свои тесты в статической библиотеке, добавьте / OPT: NOREF для параметров основного компоновщика программы. Если вы используете MSVC ++ IDE, перейдите в свойства вашего проекта .exe / Конфигурация Свойства / Компоновщик / Оптимизация и установите параметр Ссылки на Сохранить Данные без ссылок (/ OPT: NOREF). Это удержит компоновщик Visual C ++ от отбрасывание отдельных символов, сгенерированных вашими тестами из финала исполняемый файл.

Однако есть еще одна ловушка. Если вы используете Google Test в качестве статического библиотека (как это определено в gtest.vcproj) ваши тесты должны также проживать в статической библиотеке. Если вы должны иметь их в DLL, Вы должны изменить Google Test, чтобы встроить в DLL. Иначе ваши тесты не будут работать правильно или не будут работать вообще. Генерал Вывод: сделайте свою жизнь проще - не пишите свои тесты в библиотеки!

...