Компиляция существующего кода C ++ с / clr и затем вызов его из C # - PullRequest
7 голосов
/ 24 июня 2011

У меня есть некоторый код C ++:

namespace Compute {
  class __declspec(dllexport) IProgressCB {
  public:
    virtual void progress(int percentCompleted) = 0;
  };

  double __declspec(dllexport) compute(IProgressCB *progressCB, ...);
}

, из которого я создаю «compute.dll» с включенной в Visual Studio 2008 поддержкой общего языка поддержки (/ clr).

Я хочу назвать этот код из C #.

Далее я создаю консольное приложение C # и добавляю compute.dll в качестве справочного материала.Затем я пытаюсь создать подкласс / реализовать IProgressCB:

public class Progress : Compute.IProgressCB
{
    public void progress(int percentCompleted)
    {
        Console.WriteLine(percentCompleted + "% completed.");
    }
}

Однако автозаполнение VS находит пространство имен «Compute», но не какие-либо классы или функции внутри него !?Когда я пытаюсь скомпилировать;он жалуется на то, что IProgressCB не является публичным.Если я напишу публично перед объявлением IProgressCB, он будет жаловаться на то, что он не может получить производный от запечатанного типа «Compute.IProgressCB».

Что я здесь не так делаю?Я хочу взять существующий код C ++, не вносить в него никаких изменений, но скомпилировать его с / clrc, а затем использовать его из C #.Разве это не возможно?

Ответы [ 3 ]

3 голосов
/ 24 июня 2011

«Не вносите изменений» в него возможно, но вам понадобится промежуточный уровень C ++ / CLI, чтобы обернуть существующий код.C # и другие языки CLR могут «видеть» только управляемые типы, то есть ref-классы, классы-значения и т. Д. Вы не сможете избежать написания дополнительного кода C ++, просто применив / clr к существующей кодовой базе.

2 голосов
/ 24 июня 2011

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

public ref class IProgressCB
{
    // ...
};  

При этом IProgressCB будет работать совершенно иначе, чем раньше, особенно теперь управление памятью совершенно другое.

Вы можете использовать C ++ / CLI для написания управляемых оболочек для ваших существующих неуправляемых классов, но не ожидайте, что вы можете использовать неуправляемые классы C ++ из C # напрямую, просто добавив "/ clr" к ключам компилятора. Читать эту статью

http://weblogs.asp.net/kennykerr/archive/2005/07/12/Mixing-Native-and-Managed-Types-in-C_2B002B00_.aspx

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

2 голосов
/ 24 июня 2011

Ясно, что C ++ - CLI ( наследник Managed Extensions для C ++ ) не является (как) C ++. Видимость членов пространства имен - лишь малая часть разницы.

Самой большой проблемой будет недетерминированное уничтожение классов ссылок.

Я предлагаю

  1. Сначала прочтите о сборках CLR
  2. Не думайте, что C ++ больше:
  3. Сборка мусора Grok
  4. Зависимости заголовка Grok, pImpl idom и gcroot <>
  5. Теперь попробуйте библиотеку C ++ - CLI с нуля, чтобы обернуть собственную библиотеку

После 1-2 лет [1] достаточного опыта, вы сможете сказать, сколько стоит портировать собственную библиотеку C ++ 1: 1 на C ++ CLI

[1] - хорошо, может быть, вы быстро учитесь :) 1027 *

...