Почему методы класса в DLL на VC++ не видны в проекте на C#?
код h файла dll
#include <string>
#include <map>
using namespace std;
struct ConfigSetting
{
string AsString;
bool AsBool;
int AsInt;
float AsFloat;
};
typedef map<unsigned int, ConfigSetting> ConfigBlock;
namespace ConfigReader
{
public class ConfigFile
{
public:
ConfigFile();
~ConfigFile();
bool SetSource(const char *file, bool ignorecase = true);
ConfigSetting * GetSetting(const char * Block, const char * Setting);
bool GetString(const char * block, const char* name, std::string *value);
std::string GetStringDefault(const char * block, const char* name, const char* def);
std::string GetStringVA(const char * block, const char* def, const char * name, ...);
bool GetString(const char * block, char * buffer, const char * name, const char * def, unsigned int len);
bool GetBool(const char * block, const char* name, bool *value);
bool GetBoolDefault(const char * block, const char* name, const bool def);
bool GetInt(const char * block, const char* name, int *value);
int GetIntDefault(const char * block, const char* name, const int def);
int GetIntVA(const char * block, int def, const char* name, ...);
bool GetFloat(const char * block, const char* name, float *value);
float GetFloatDefault(const char * block, const char* name, const float def);
float GetFloatVA(const char * block, float def, const char* name, ...);
private:
map<unsigned int, ConfigBlock> m_settings;
};
}
Есть у меня проект на C#, в котором мне надо использовать методы класса из этой DLL. Я подключаю ее в references, объявляю класс, однако методы описание в DLL не видны :( Есть только 4 стандартных Equals, GetHashCode, GetType и ToString.
cnfg.
Исходники DLL приложены к посту. Может кто сказать в чем ошибка?
1) ошибка архитектурная - использовании C++/CLI для такой пустяковины, как разбор конфига.
2) синтаксическая - у вас не CTS-совместимый класс (читайте об ref class).
3) концептуальная. Вы всеравно не сможете нормально работать с этим классом, так как строки в .NET это не char* и не std::string, а экземпляры System.String.
На досуге подумаю что лучше, исправить их или встроить конфиг ридер в проект на С#.
Дело-то в том что этот проект на VC++ уже был готов, а чтоб сделать другой, надо его делать :)
Ошибки нету.
На С++ делается Native DLL - содержит двоичный код
referense же подгружает сборки(DLL, которые содержат промежуточный язык, работающий на платформе NET)
Поэтому у вас два выхода:
1) Писать оболочку на С#, при этом:
Через DllImport[...] выдергивать из вашей dll функции.
Причем все указатели C++ будут передаваться как IntPtr
Что то типа:
public static extern int fScanf(IntPtr FILE, out int rInt);
2) Написать сборку на С++.NET(Там можно хитро в Manadged функции вплетать неуправляемый код и функции)
P.S
Скидываю вам 2 примера на оба случая !!!
Файл Native.FStream.cs - это обертка для Native.FStream.cpp
Второй вариант я врятли смогу сделать, ибо не знаю как исправить те ошибки, что возникают когда я делаю класс управляемым, а вот сделать натив длл и юзать ее из обертки запросто :) Не знаю правда как там выкручиваться с char* и std::string, но посмотрю. Премного благодарен
Вот это как раз при DllImport очень просто. Все сделает PInvoke(хотя он и сильно тормозит программу, так как все параметры подвергаются маршаллингу, а принимаются как VARIANT)
Допустим native функция funk(char* str, FILE* F) в C# дергается как funk(string str, IntPtr F)
А вот с std::string сложнее - это контейнер. Нужно наверное его будет в char* преобразовать.
System::String вообще говоря, хранит информацию в Unicode. Однако, имеет конструктор, принимающий ASCIIZ-строки в качестне аргумента. Обёртку сделать - два пальца об асфальт, но... Вопрос: зачем всё это, если в .NET есть отличные средства решения вашей задачи? Кроме того, CIL-сборки с неуправляемым кодом не приветствуются системой безопасности .NET.