Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.08.2011, 22:40   #1
BadProgrammer
Пользователь
 
Аватар для BadProgrammer
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию Простой вопрос про DLL.

Здравствуйте!
Задачка такова:
Дано: исходник Visual C++; исходник Visual C#.
Что нужно сделать: как-нибудь связать эти два исходника воедино, пробилдив Visual C++ в DLL, а Visual C# в EXE и "прикрепив" DLL к EXE. Подскажите, как это всё провернуть или как сделать по-другому без переписывания.
Заранее благодарен.
BadProgrammer вне форума Ответить с цитированием
Старый 02.08.2011, 10:05   #2
xwicked
Участник клуба
 
Аватар для xwicked
 
Регистрация: 21.03.2010
Сообщений: 1,508
Лампочка Как-то так...

Код C++ подготавливаете к dll. Создаёте проект библиотеки, переносите все функции туда.

В проекте C# создаёте вызовы необходимых функций из свежесозданной библиотеки. Можете использовать статическое связывание.

ЗЫ: Это всё, что я могу сказать, без конкретизации и Ваших пояснений.
Google - лучший помощник программиста.
---
моя лаборатория | мой FaceBook
xwicked вне форума Ответить с цитированием
Старый 03.08.2011, 18:11   #3
BadProgrammer
Пользователь
 
Аватар для BadProgrammer
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию

Поясняю:
Насколько я знаю, есть 2 способа связывания библиотек: неявный и явный.
Неявный способ предполагает наличие файлов .h, .lib и .dll. Этот способ прост.
Явный способ сложен, но предполагает наличие только .dll.
Я выбрал неявный способ (он проще). Но есть одна несостыковка: заголовочный (.h) файл-то будет написан на C++, а не на C#. Получается, мне придется добавить в проект C# файл на языке C++? Мне кажется, с этим будут проблемки...
BadProgrammer вне форума Ответить с цитированием
Старый 03.08.2011, 18:16   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

придется писать DllImport, а заголовочники вообще не причем, в шарпе нет такого понятия.

вот кусок для размышления:
Код:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Collections.Generic;

namespace phLibrary.Graphic.OpenGL
{
    sealed public class Context
    {
        [DllImport("phLibrary.Graphic.OpenGL.Helper.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr phLibrary_Graphic_OpenGL_Helper_CreateContext(IntPtr wnd);
        [DllImport("phLibrary.Graphic.OpenGL.Helper.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern void phLibrary_Graphic_OpenGL_Helper_DeleteContext(IntPtr gl);
        [DllImport("phLibrary.Graphic.OpenGL.Helper.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr phLibrary_Graphic_OpenGL_Helper_BeginPaint(IntPtr wnd, IntPtr gl);
        [DllImport("phLibrary.Graphic.OpenGL.Helper.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern void phLibrary_Graphic_OpenGL_Helper_EndPaint(IntPtr wnd, IntPtr dc);
        public enum BeginMode:uint
        {
            GL_POINTS=0x0000,
            GL_LINES=0x0001,
            GL_LINE_LOOP=0x0002,
            GL_LINE_STRIP=0x0003,
            GL_TRIANGLES=0x0004,
            GL_TRIANGLE_STRIP=0x0005,
            GL_TRIANGLE_FAN=0x0006,
            GL_QUADS=0x0007,
            GL_QUAD_STRIP=0x0008,
            GL_POLYGON=0x0009
        }
        [DllImport("opengl32.dll",CallingConvention=CallingConvention.StdCall)]
        public static extern void glBegin(BeginMode mode);
а вот заголовок phLibrary.Graphic.OpenGL.Helper.dll
Код:
HGLRC __stdcall phLibrary_Graphic_OpenGL_Helper_CreateContext(HWND window);
void __stdcall phLibrary_Graphic_OpenGL_Helper_DeleteContext(HGLRC rc);
HDC __stdcall phLibrary_Graphic_OpenGL_Helper_BeginPaint(HWND wnd,HGLRC rc);
void __stdcall phLibrary_Graphic_OpenGL_Helper_EndPaint(HWND wnd,HDC dc);
(я применял экспорт через def файл)
ну и деф файл уж выложу:
Код:
LIBRARY	"phLibrary.Graphic.OpenGL.Helper.dll"
EXPORTS
	phLibrary_Graphic_OpenGL_Helper_CreateContext
	phLibrary_Graphic_OpenGL_Helper_DeleteContext
	phLibrary_Graphic_OpenGL_Helper_BeginPaint
	phLibrary_Graphic_OpenGL_Helper_EndPaint
Цитата:
Неявный способ предполагает наличие файлов .h, .lib и .dll.
имея dll, lib файл сварганить не трудно.
с .h труднее, но там немного нужно исправить явный заголовочник обычно(или просто взять сигнатуры функций)
Цитата:
Я выбрал неявный способ (он проще).
на самом деле в шарпе всегда явный применяется, просто через DllImport он автоматически, и потому прост.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 03.08.2011 в 18:23.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.08.2011, 21:18   #5
BadProgrammer
Пользователь
 
Аватар для BadProgrammer
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию

2 Пепел Феникса
Немного не понял... Начнем по-порядку:
1) DllImport — поначалу были вопросы о нем, но поискал в MSDN и нашел для себя ответы. Итак, насколько я понял, эта... хм... функция определяет откуда импортируется функция/переменная/что-либо-ещё. Это верно?
2) Немного я был запутан Вашим кодом... Насколько я понял, код распределяется вот так:
Код:
namespace phLibrary.Graphic.OpenGL
{
    sealed public class Context
...
Код в клиенте
Код:
HGLRC __stdcall phLibrary_Graphic_OpenGL_Helper_CreateContext(HWND window);
...
Код в библиотеке
Код:
LIBRARY	"phLibrary.Graphic.OpenGL.Helper.dll"
...
Код в библиотеке
3)
Код:
EXPORTS
	phLibrary_Graphic_OpenGL_Helper_CreateContext
	phLibrary_Graphic_OpenGL_Helper_DeleteContext
	phLibrary_Graphic_OpenGL_Helper_BeginPaint
	phLibrary_Graphic_OpenGL_Helper_EndPaint
Обязательно называть функции так? Или можно назвать, к примеру так:
Код:
EXPORTS
	CreateContext
	DeleteContext
	BeginPaint
	EndPaint
Или эти названия сделаны так только для повышения читаемости?

Если все пункты верны, то я разобрался.

Цитата:
Насколько я знаю, есть 2 способа связывания библиотек: неявный и явный.
Неявный способ предполагает наличие файлов .h, .lib и .dll. Этот способ прост.
Явный способ сложен, но предполагает наличие только .dll.
Эти способы можно использовать для обхода def-файлов. Дело в том, что, насколько я понял из MSDN, def — плохо, а __declspec (dllexport) — хорошо. Но раз уж опытный программист использует def, то почему бы и мне его не запрячь.

[update спустя пару минут]
Ещё пару вопросов:
Про импорт/экспорт я, более-менее, понял. Я связывание?
Мне следует поступить вот так?
А вот, кстати хороший ресурс про def-файлы.

Последний раз редактировалось BadProgrammer; 04.08.2011 в 21:37.
BadProgrammer вне форума Ответить с цитированием
Старый 05.08.2011, 02:14   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

1)DllImport это указание dotNET среде загрузить длл и импортировать указанную функцию, ну и потом вы можете её выполнить.
2)да, верно.
3)
Цитата:
Дело в том, что, насколько я понял из MSDN, def — плохо, а __declspec (dllexport) — хорошо.
не знаю где вы это вычитали, я на том же мсдн читал что __declspec (dllexport) удобно применять для связи длл/проекта написанных на одном компиляторе.
def же менее удобен(надо ручками вносить функцию), но позволяет твердо быть увереным в имени экспорта функции, что позволит применять длл практически с чем угодно.
Цитата:
Или эти названия сделаны так только для повышения читаемости?
для читаемости и отсутствия конфликта(а вообще закос под С++/С#, а именно под полное имя функции/метода(включая пространства имен и класс))
Цитата:
Я связывание?
а собственно DllImport и есть связывание, при первом вызове функции будет загружена длл и найден указатель на функцию(кстати этот момент может выкинуть исключение если длл/функция не найдена) и затем она уже вызвана, то есть все автоматически.

у меня в коде было это:
Код:
        [DllImport("phLibrary.Graphic.OpenGL.Helper.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        private static extern IntPtr phLibrary_Graphic_OpenGL_Helper_CreateContext(IntPtr wnd);
        public Context(Control comp)
        {
            window=comp.Handle;
            glrc=phLibrary_Graphic_OpenGL_Helper_CreateContext(window);
            dc=IntPtr.Zero;
        }
и все, никаких телодвижений я более не делал.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.08.2011, 18:31   #7
BadProgrammer
Пользователь
 
Аватар для BadProgrammer
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию

Всё, теперь я почти разобрался.
Почитал вот этот ресурс, но остались некоторые вопросы, которые я задам, так сказать, для полной ясности.

Там написано так (секция Remarks, первый абзац):
Цитата:
If an unmanaged DLL file is included in an assembly, for example, by using the linker or the /linkresource compiler option, you can specify the assembly display name as part of dllName. For example, if an unmanaged DLL named unmanaged.dll is included in a managed assembly named MyAssembly, the attribute might be specified as shown in the following code.
Что переводится примерно так (ручной перевод, может быть неточным):
Цитата:
Если неуправляемая DLL включена в билд, для примера, с помощью ссылок или параметра компилятора «/linkresource», то Вы можете задать имя билда, как часть dllName.[и дальше пояснения к примеру на MSDN...]
Т.е. параметр dllName должен быть не просто полным именем файла DLL, этот файл нужно еще и связать перед построением проекта. Насколько я понял, это делается как вот тут в пункте «Использование функциональных возможностей библиотеки классов в консольном приложении» №2-3, только вместо проекта добавить файл .dll. Это так? Или там тоже всё иначе?

Еще было пару вопросов про def-файлы, но, думаю, я сам найду ответы, так что не будут Вас без нужды отвлекать.

[update через минуту]
Нашел русскую версию справки про DllImport.

Последний раз редактировалось BadProgrammer; 05.08.2011 в 18:33.
BadProgrammer вне форума Ответить с цитированием
Старый 05.08.2011, 18:34   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

это ЕСЛИ
при простом импорте ничего не надо делать(кроме того что ДЛЛ должна быть доступна по имени сразу)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.08.2011, 18:42   #9
BadProgrammer
Пользователь
 
Аватар для BadProgrammer
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию

Значит параметр dllName должен быть полным именем файла?
BadProgrammer вне форума Ответить с цитированием
Старый 05.08.2011, 18:50   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну да, первый параметр это имя длл.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос про dll и сообщения HollyPaladin Win Api 8 21.10.2010 11:30
Простой вопрос про память Les_55 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 9 17.12.2009 12:28
Вопрос про классы в DLL. Вадим Буренков Общие вопросы Delphi 15 14.09.2009 18:36
Вопрос про DLL R@# Общие вопросы Delphi 11 21.06.2009 12:26
Вопрос про DLL-файлы PChEL@ Общие вопросы Delphi 3 29.06.2007 02:03