Как я называю C++ / CLI от C#?

Мне реализовали класс в C++, это ответственно за арифметическое вычисление программы и интерфейс с помощью WPF. Я обрабатываю вход с C#, но затем как я могу использовать свой класс C++?

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

Что-нибудь там для выручения меня? Это не кажется неблагоразумным мне.

EDIT Испытанное m3rLinEz решение, но это дает мне BadImageFormatException, я думаю, что это - потому что DLL не сгенерирован. Я сделал все, как сказали, не знайте то, что произошло. Какие-либо идеи?

64
задан Quonux 22 May 2017 в 14:06
поделиться

4 ответа

Вы когда-нибудь взглянули на C ++ / CLI?

Позвольте мне привести очень короткий пример. Вот исходный файл из проекта Visual C ++ -> CLR -> Class Library. Он в основном получает имя пользователя Windows и возвращает его.

Обратите внимание, что для того, чтобы это скомпилировать, вы должны войти в настройки проекта и отметить «Дополнительные зависимости» как «Наследовать от родителя», потому что мы используем эти библиотеки Windows (kernel32.lib, user32.lib,. .)

// CSCPP.h

#pragma once

#include "windows.h"

using namespace System;

namespace CSCPP {

    public ref class Class1
    {
        // TODO: Add your methods for this class here.
    public:
        String^ GetText(){
            WCHAR acUserName[100];
            DWORD nUserName = sizeof(acUserName);
            if (GetUserName(acUserName, &nUserName)) {
                String^ name = gcnew String(acUserName);
                return String::Format("Hello {0} !", name);
            }else{
                return gcnew String("Error!");
            }
        }
    };
}

Теперь создан новый проект C # и добавлена ​​ссылка на наш первый проект библиотеки классов C ++ / CLI. А затем вызовите метод экземпляра.

namespace CSTester
{
    class Program
    {
        static void Main(string[] args)
        {
            CSCPP.Class1 instance = new CSCPP.Class1();
            Console.WriteLine(instance.GetText());
        }
    }
}

На моей машине это дало следующий результат:

Здравствуйте, m3rlinez!

C ++ / CLI - это, по сути, управляемое расширение по сравнению со стандартом C ++. Это позволяет вам использовать классы и типы данных CLR в вашем проекте C ++ / CLI, а также предоставлять их управляемому языку. Вы можете создать управляемую оболочку для своей старой библиотеки C ++, используя это. Есть несколько странных синтаксисов, таких как String ^ для определения ссылочного типа для CLR String. Я считаю полезным «Быстрый C ++ / CLI - Изучите C ++ / CLI менее чем за 10 минут» .

56
ответ дан 24 November 2019 в 16:00
поделиться

Мой 2с: Цепочка владения унаследована. Он датируется днями, когда не было альтернатив, и по сравнению с сегодняшними альтернативами является небезопасным и грубым.

Я говорю, что альтернатива - это не разрешения схемы, а подписывание кода. При подписании кода можно предоставить необходимые разрешения на подпись процедуры и предоставить широкий доступ к выполнению процедуры, в то время как доступ к данным строго контролируется. Подписание кода обеспечивает более детальный и точный контроль, и нельзя злоупотреблять способом, которым может быть цепочка владения. Он работает внутри схемы, он работает по всей схеме, он работает по всей базе данных и не требует, чтобы огромное отверстие безопасности цепочки владения между базами данных было открыто. И не требует угона объекта собственности в целях доступа: владельцем процедуры может быть любой пользователь.

Что касается второго вопроса о безопасности на уровне строк: безопасность на уровне строк в SQL Server версий 2014 и более ранних на самом деле не существует, как функция, предлагаемая механизмом. У вас есть различные обходные пути, и эти обходные пути работают на самом деле лучше с подписыванием кода, чем с цепочкой владения. Поскольку маркер sys.login _ содержит сигнатуры контекста и контрасначертания, можно выполнить более сложные проверки, чем в контексте цепочки владения.

Начиная с версии 2016 SQL Server полностью поддерживает безопасность на уровне строк .

-121--1495237-

Я бы просто использовал пакет объявлений и сделал отступление с местами или вкладками. Я полагаю, что вы все равно используете шрифт пишущей машинки, чтобы получить буквы с неродственной шириной.

-121--4088937-

Существует как минимум три способа вызова неуправляемого кода из управляемого процесса:

  1. C + +/CLI
  2. Platform Invoke
  3. Переносить C++ в COM-объект

На работе мы используем C + +/CLI для этого, похоже, работает.

9
ответ дан 24 November 2019 в 16:00
поделиться

Я бы создал стандартную (не управляемую / управляемую) библиотеку динамической компоновки, как , описанную здесь , а затем использовал бы атрибут DllImport (вызов платформы) в коде C # для доступа к экспортированному функции.

Ключевой момент из этой статьи:

Обратите внимание на модификатор __declspec (dllexport) в объявлениях методов в этом коде. Эти модификаторы позволяют экспортировать метод библиотекой DLL, чтобы его могли использовать другие приложения. Для получения дополнительной информации см. Dllexport, dllimport.

Это более легкая альтернатива реальной оболочке COM-взаимодействия, позволяющая избежать таких проблем, как регистрация и т. Д. (DLL можно просто поместить в каталог приложения) .

Другой альтернативой является Это просто работает (IJW). Вероятно, это лучший выбор, если вы управляли кодом C ++ и вам нужно получить к нему доступ из других языков .NET. Но это вариант только в том случае, если вы можете / счастливы преобразовать свой неуправляемый C ++ в управляемый C ++.

4
ответ дан 24 November 2019 в 16:00
поделиться

Я бы держался подальше от P / Invoke поскольку он довольно медленный по сравнению с IJW (It Just Works). Последний позволяет легко переплетать управляемый и неуправляемый C ++. Все, что вам нужно сделать, это создать управляемую сборку C ++, написать управляемый класс, видимый из C #, и вызвать из него неуправляемый код.

Эээ ... Хорошо. У меня создалось впечатление, что вызовы P / Invoke были медленнее, чего не было изначально.Однако, обладая явным контролем над маршалингом, вы можете улучшить работу своей версии C ++ / CLI во многих случаях.

Вот статья Microsoft об обоих механизмах:

http://msdn.microsoft.com/en-us/library/ms235282.aspx

Преимущества IJW

  • Нет необходимости писать атрибут DLLImport объявления для неуправляемых API , которые использует программа. Просто включите файл заголовка и свяжите его с библиотекой импорта.
  • Механизм IJW немного быстрее (например, заглушкам IJW не нужно проверять необходимость закрепления или копирования элементов данных, потому что это делается явно от разработчика).
  • Это ясно показывает проблемы с производительностью. В данном случае это тот факт, что вы переводите из строки Unicode в строку ANSI и что у вас есть вспомогательное выделение памяти и освобождение. В этом случае разработчик, пишущий код с использованием IJW , поймет, что вызов _putws и с использованием PtrToStringChars будет более для повышения производительности.
  • Если вы вызываете множество неуправляемых API, использующих одни и те же данные, один раз маршалинг и передача маршалированной копии намного эффективнее, чем повторный маршалинг каждый раз.

Есть и эстетические преимущества:

  • Код C # выглядит как код C # без каких-либо странностей взаимодействия.
  • Вам не нужно определять атрибут DLLImport , вам не нужно определять какие-либо структуры данных (также с определенными атрибутами p / invoke), которые могут выглядеть следующим образом:

    { {1}}

    [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)] общедоступная структура DevMode { [MarshalAs (UnmanagedType.ByValTStr, SizeConst = 32)] общедоступная строка dmDeviceName; }

  • Вам не нужно преобразовывать все примитивные типы параметров в их аналоги в .NET (есть таблица на здесь страница , в которой показано, как управляемые типы сопоставляются с неуправляемыми типами).
  • Вы начинаете работать с C ++ / CLI, изучать который действительно интересно и который действительно отточен. Он прошел долгий путь со времен VS 2003 и теперь является полнофункциональным языком .NET. Документация Microsoft по этому поводу довольно хороша, как и вся информация IJW.
  • Взаимодействие с C ++ в C ++ / CLI кажется очень естественным, в отличие от C #. Это полностью субъективно, но я бы предпочел выполнять маршалинг строк на C ++, который выполняет Marshal.PtrToString (ptr) .
  • Если вы открываете API, вы, вероятно, захотите обернуть все вещи P / Invoke на другом уровне, чтобы вам не приходилось иметь дело с уродством P / Invoke. Таким образом, у вас есть накладные расходы на всю сортировку и слой C # вокруг него. В C ++ / CLI маршаллинг и абстракция взаимодействия находятся в одном месте, и вы можете выбрать, какой уровень маршалинга вам нужен.

IMHO, если вы вызываете странную функцию в Windows SDK, используйте P / Invoke. Если вы представляете умеренно сложный C ++ API управляемому миру, определенно C ++ / CLI.

3
ответ дан 24 November 2019 в 16:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: