Вызов программ на C # из D - PullRequest
0 голосов
/ 30 января 2019

Как я могу вызвать функции C # (DLL) из D?

Я пытался или смотрю на следующее:

Подход Derelict Mono хорошо работает для программ Hello World, однако большая библиотека DLL (со ссылками на множество других сборок, каждая из которых может использовать или не использовать подлинные вызовы Windows API) не работает, поскольку библиотека DLL работает неправильнозагружен.

Первоначальные эксперименты с неуправляемым экспортом приводят к ошибкам с MSBUILD.

Ответы [ 3 ]

0 голосов
/ 06 августа 2019

Попробуйте следующее.Сначала код D:

module main;
import std.stdio;
import std.conv;

extern (C++) ulong receiveMe(ulong i);
extern (C++) ulong freeMe(ulong i);

void main() {
    ulong l = receiveMe(0);
    char* p = cast(char*)l;
    char[] s = to!(char[])(p);
    byte[] b = cast(byte[])(s.dup);
    writeln("The answer is " ~ to!string(s));
    ulong m = freeMe(0);
}

Затем прокладка C ++ / CLI:

#include "stdafx.h"
#using "...\CS-Interop\bin\x64\Debug\netstandard2.0\CS-Interop.dll"

using namespace System;

UInt64 sendMe(UInt64 arg) {
    return CS_Interop::Test::receiveMe(42);
}

UInt64 freeMe(UInt64 arg) {
    return CS_Interop::Test::freeMe(42);
}

Наконец C #:

using System.Runtime.InteropServices;
using System.Text;

namespace CS_Interop {

    public class Test {

        public static byte[] buffer;

        public static GCHandle gcbuf;

        public static ulong receiveMe(ulong arg) {
            string s = "I was a string " + arg;
            s = (s.Length + 2) + s;
            buffer = Encoding.ASCII.GetBytes(s);
            gcbuf = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            ulong l = (ulong)gcbuf.AddrOfPinnedObject();
            return l;
        }

        public static ulong freeMe(ulong arg) {
            gcbuf.Free();
            return 42;
        }
    }
}

Я все еще смотрю на способычтобы избавиться от этой прокладки C ++ / CLI.

Этот код написан таким образом, что вы можете возиться с отладчиком VS.

Это очень просто настроить и протестировать вVisual Studio.С установленным Visual D, сначала настройте проект C ++ / CLI (НЕ проект Visual D) и оставьте там код D и C ++.Затем настройте проект C # DLL в рамках проекта D.

Одно дело вызвать код C # из D, но другое - получить данные обратно, если вы не используете только простые скалярные типы, такие как int.Ключевыми строками C # являются

gcbuf = GCHandle.Alloc(buffer, GCHandleType.Pinned);
ulong l = (ulong)gcbuf.AddrOfPinnedObject();

, где вам сначала нужно закрепить вещь, которую вы отправляете обратно, а затем отправить адрес обратно D. Нет никакого утомительного хулиганства с маршалингом вчасть C ++, ваш D-код должен быть в состоянии справиться с тем, что находится за указателем.

Обязательно освободите закрепленный указатель, как только вы закончите с ним.Закомментируйте строку freeMe в D-коде и наблюдайте рост (и рост) использования памяти в VS.

Лично я нахожу процесс pin немного изменчивым, поскольку GCHandle.Alloc будет работать только тогда, когда его первый аргумент, будь то байтовый массив или структура, содержит blittable предметов.

См. Также https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types

0 голосов
/ 08 августа 2019

Вы можете использовать Неуправляемый экспорт для вызова C # из D. Я сделал это без проблем.

См. https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

Однако, когда я попробовал Неуправляемый экспорт с Visual Studio 2017,Я также не мог заставить его работать.Неуправляемый экспорт хорошо работал с VS2015.Учитывая, что ссылка была с июля 2009 года, другие аспекты могли бы устареть.

Обязательно внимательно прочитайте инструкции и, самое главное, убедитесь, что вы собираете для x86 или x64, а не для "любого процессора".Распределение данных будет еще одной проблемой.

0 голосов
/ 05 февраля 2019

У меня есть предварительное решение для передачи строки из D в (небольшое количество) C ++ в C # на основе следующих статей: (Я отказался от неуправляемого экспорта от Роберта Гизеке)

C # "Неуправляемый экспорт " (учебник от Ханса Пассанта)

Вызов функции C # из C ++ / CLI - преобразование возвращаемой строки C # в строку C

Интеграция D в C ++с Visual D просто работает.

https://rainers.github.io/visuald/visuald/vcxproject.html (см. Интеграция проекта Visual C / C ++)

https://dlang.org/spec/cpp_interface.html

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