Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Почему методы класса в DLL на VC++ не видны в проекте на C#?

408
27 февраля 2009 года
Lei fang
265 / / 01.10.2005
Здравствуйте. Никогда раньше не занимался такими вещами и не пробовал так сделать, но появилась необходимость... Есть у меня проект на VC++, который занимается чтением конфиг файлов и компилится в виде DLL.

код h файла dll
Код:
#include <stdarg.h>
#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.
 
Код:
ConfigReader.ConfigFile cnfg = new ConfigReader.ConfigFile();
cnfg.


Исходники DLL приложены к посту. Может кто сказать в чем ошибка?
5
27 февраля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: Lei fang
Исходники DLL приложены к посту. Может кто сказать в чем ошибка?


1) ошибка архитектурная - использовании C++/CLI для такой пустяковины, как разбор конфига.
2) синтаксическая - у вас не CTS-совместимый класс (читайте об ref class).
3) концептуальная. Вы всеравно не сможете нормально работать с этим классом, так как строки в .NET это не char* и не std::string, а экземпляры System.String.

408
27 февраля 2009 года
Lei fang
265 / / 01.10.2005
Мда, теперь ясно что основная ошибка была в том, что класс надо было объявить как public ref class ConfigFile, однако с этим вылазиет еще 24 новых ошибки при компиляции :) Спасибо, я узнал кое что новое ))
На досуге подумаю что лучше, исправить их или встроить конфиг ридер в проект на С#.
Дело-то в том что этот проект на VC++ уже был готов, а чтоб сделать другой, надо его делать :)
842
27 февраля 2009 года
sigmov
301 / / 16.09.2008
Цитата: Lei fang
Есть у меня проект на C#, в котором мне надо использовать методы класса из этой DLL. Я подключаю ее в references, объявляю класс, однако методы описание в DLL не видны :( Есть только 4 стандартных Equals, GetHashCode, GetType и ToString.



Ошибки нету.

На С++ делается Native DLL - содержит двоичный код
referense же подгружает сборки(DLL, которые содержат промежуточный язык, работающий на платформе NET)

Поэтому у вас два выхода:

1) Писать оболочку на С#, при этом:
Через DllImport[...] выдергивать из вашей dll функции.
Причем все указатели C++ будут передаваться как IntPtr

Что то типа:

 
Код:
[DllImport("Native.FStream.dll",EntryPoint = "FScanfInt")]
public static extern int fScanf(IntPtr FILE, out int rInt);


2) Написать сборку на С++.NET(Там можно хитро в Manadged функции вплетать неуправляемый код и функции)

P.S
Скидываю вам 2 примера на оба случая !!!
Файл Native.FStream.cs - это обертка для Native.FStream.cpp
408
27 февраля 2009 года
Lei fang
265 / / 01.10.2005
Прикольные штуки :P
Второй вариант я врятли смогу сделать, ибо не знаю как исправить те ошибки, что возникают когда я делаю класс управляемым, а вот сделать натив длл и юзать ее из обертки запросто :) Не знаю правда как там выкручиваться с char* и std::string, но посмотрю. Премного благодарен
842
28 февраля 2009 года
sigmov
301 / / 16.09.2008
Цитата: Lei fang
Не знаю правда как там выкручиваться с char* и std::string, но посмотрю



Вот это как раз при DllImport очень просто. Все сделает PInvoke(хотя он и сильно тормозит программу, так как все параметры подвергаются маршаллингу, а принимаются как VARIANT)

Допустим native функция funk(char* str, FILE* F) в C# дергается как funk(string str, IntPtr F)

А вот с std::string сложнее - это контейнер. Нужно наверное его будет в char* преобразовать.

341
28 февраля 2009 года
Der Meister
874 / / 21.12.2007
[QUOTE=Lei fang]Дело-то в том что этот проект на VC++ уже был готов, а чтоб сделать другой, надо его делать :)[/QUOTE]Дело в том, что делать его - час, от силы. :)[QUOTE=Lei fang]а вот сделать натив длл и юзать ее из обертки запросто :)[/QUOTE]PInvoke не поддерживает C++-классы. Придётся делать функции глобальными.

System::String вообще говоря, хранит информацию в Unicode. Однако, имеет конструктор, принимающий ASCIIZ-строки в качестне аргумента. Обёртку сделать - два пальца об асфальт, но... Вопрос: зачем всё это, если в .NET есть отличные средства решения вашей задачи? Кроме того, CIL-сборки с неуправляемым кодом не приветствуются системой безопасности .NET.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог