Головна Обговорення Лінки Пошук Prykladna СС Прикладна _КОЛЕДЖ 27.07.2026 19:17:25 (EEST=GMT+2)
ACM -
Навігація -
Теми форуму +
Чи знали ви, що... ? (beta) -
Код: ... float x = 1e8; while (x > 0) --x; ... може дати зациклення, використовуйте double. (Це тому, що через малу точність float операція "--x" не змінює x)
Події
ПнВтСрЧтПтСбНд
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Birthday(s):
AVATARMargarita
AVATARSovyak
AVATARaltes
AVATARwowa kalinyak
AVATARChizh
AVATARNT
AVATARlevi

Перегляд теми
ACM Контестер | Теревені | Про глобальні питання
Автор С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 05-05-2008 22:28
Тема для запитань і відповідей про мову прогамування С++
Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 05-05-2008 22:30
Люди, хтось знає, як створити бібліотеку (*.DLL) з різними функціями і т.д. на С++? Чи це взагалі неможливо..?
Надіслати приватне повідомлення
Автор RE: С++
webmaster
Головний Адміністратор

Аватар користувача

Повідомлень: 1136
Зареєстрований: 17.03.07
Опубліковано 06-05-2008 00:35
Якщо можна створити *.exe файл значить можна створити і *.dll файл.

Для початку потрібно вказати властивості проекту, щоб воно компілювало в *.dll файл.
Наприклад у Студії коли створюєш проект, то там у діалоговому вікні можна вибрати DLL. Але також можна і потім змінити властивості проекту Project/Properties/Configuration Properties/General/Configuration Type (і унших версіях може бути по інкшому).

А далі іде сам код, який трохи відрізнається від коду звичайних аплікацій.

Приклад деяких функцій на мові С++
  1. #include <windows.h>
  2. #include <string>
  3. using namespace std;
  4.  
  5. extern "C" __declspec(dllexport) int __stdcall sum(int a, int b)
  6. {
  7. return a+b;
  8. }
  9.  
  10. extern "C" __declspec(dllexport) int __stdcall sub(int a, int b)
  11. {
  12. return a-b;
  13. }
  14.  
  15. extern "C" __declspec(dllexport) int __stdcall strlen2(LPSTR c)
  16. {
  17. string s(c);
  18. return s.size();
  19. }



Приклад цих же функцій на мові Pascal
  1. library DelphiDLL;
  2. {$APPTYPE CONSOLE}
  3.  
  4. function sum(a,b : integer) : integer; stdcall;
  5. begin
  6. Result := a + b;
  7. end;
  8.  
  9. function sub(a,b : integer) : integer; stdcall;
  10. begin
  11. Result := a-b;
  12. end;
  13.  
  14. function strlen2(ins : PChar) : integer; stdcall;
  15. var
  16. s : string;
  17. begin
  18. s := ins;
  19. Result := length(s);
  20. end;
  21.  
  22. exports
  23. sum,
  24. sub,
  25. strlen2;
  26. end.



Модифікатором (extern "C") потрібний для того, щоб можна було викликати функції по назві. Бо компілятори С++ насправді переназивають функцію. У новій назві враховується кількість і типи параметрів. Це дає змогу сторювати функції з однаковими назвами, але різними параметрами, що у бінарних файлах (*.exe, *.dll) не допустимо.

А модифікатор "stdcall" щоб відбувалося однозначне розгортання стеку.
Змінив(ла) webmaster, 06-05-2008 00:47
brus07 brus07 (Lviv NU) http://acm.lviv.ua Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 06-05-2008 21:33
Дуже дякую. А чи можна в Delphi користуватися бібліотекою з C++?
Надіслати приватне повідомлення
Автор RE: С++
webmaster
Головний Адміністратор

Аватар користувача

Повідомлень: 1136
Зареєстрований: 17.03.07
Опубліковано 07-05-2008 00:07
Звісно можна.
Головне щоб модифікари були потрібні вказані.

Ось наприклад код на мові C#, використання вище наведених фукнцій
  1.  
  2. namespace sol
  3. {
  4. class Program
  5. {
  6. [DllImport(@"a.dll", EntryPoint = "sum", CallingConvention = CallingConvention.StdCall)]
  7. private static extern int sum(int a, int b);
  8.  
  9. static void Main(string[] args)
  10. {
  11. int a = 123;
  12. int b = 321;
  13. int res = sum(a, b);
  14. }
  15. }
  16. }


Змінив(ла) webmaster, 07-05-2008 00:11
brus07 brus07 (Lviv NU) http://acm.lviv.ua Надіслати приватне повідомлення
Автор RE: С++
DixonD
Модератор

Повідомлень: 167
Звідки: ЛНУ ім. Івана Франка
Зареєстрований: 21.10.06
Опубліковано 07-05-2008 08:45
В Delphi достатньо описати цю функцію, наприклад
  1. function sum(a,b:integer);stdcall;cdecl; external 'a.dll';


Інший варіант - використати функцію LoadLibrary
Змінив(ла) webmaster, 08-05-2008 00:06
DixonD 427265719 dixond[злий_пес]acm[на]lviv[на]ua DixonD (Lviv NU) http://dixond.blogspot.com/ Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 09-05-2008 18:39
В мене компілятор (Visual Studio 6.0) в DLL функцію sum перейменовує на _sum@8.
І ще одна проблема: ця функція в Delphi (з DLL) видає неправильні результати (якісь від'ємні числа).
Надіслати приватне повідомлення
Автор RE: С++
ibm
Користувач

Аватар користувача

Повідомлень: 422
Звідки: LPML
Зареєстрований: 21.02.07
Опубліковано 05-06-2008 23:05
DixonD написав:
В Delphi достатньо описати цю функцію, наприклад
  1. function sum(a,b:integer);stdcall;cdecl; external 'a.dll';




Не обов'язково писати назву функції?
  1. function LoadLibraryEx(LibName: PChar; hFile: Longint; Flags: Longint): Longint; stdcall;
  2. external 'kernel32.dll' name 'LoadLibraryExA';




Pascal not dead!
ibmua 353747640 ibm http://code.knopok.net/ Надіслати приватне повідомлення
Автор RE: С++
Oracle
Користувач

Повідомлень: 75
Звідки: LNU FAMI-13
Зареєстрований: 20.02.07
Опубліковано 06-06-2008 12:18
Назву треба писати тільки якщо вона не співпадає з назвою функції в ДЛЛці. Наприклад в твому прикладі ти експортуєш функцію LoadLibraryEx, а в ДЛЛ вона називається LoadLibraryExA - в таких випадках назву писати треба. А от коли б ти експортував LoadLibraryExA, то назву можна б було не писати.
_Oracle 492-581-744 Oracle[Lviv NU] Надіслати приватне повідомлення
Автор RE: С++
ibm
Користувач

Аватар користувача

Повідомлень: 422
Звідки: LPML
Зареєстрований: 21.02.07
Опубліковано 08-06-2008 11:55
Зрозуміло, дякую:)


Pascal not dead!
ibmua 353747640 ibm http://code.knopok.net/ Надіслати приватне повідомлення
Автор RE: С++
ibm
Користувач

Аватар користувача

Повідомлень: 422
Звідки: LPML
Зареєстрований: 21.02.07
Опубліковано 12-06-2008 22:15
Доречі!
webmaster написав:
  1. library DelphiDLL;
  2. {$APPTYPE CONSOLE}
  3.  
  4. function sum(a,b : integer) : integer; stdcall;
  5. begin
  6. Result := a + b;
  7. end;
  8.  
  9. ...




Хелп Дельфи каже:
The $APPTYPE directive is meaningful only in a program. It should not be used in a library, unit, or package.



Pascal not dead!
ibmua 353747640 ibm http://code.knopok.net/ Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 12-06-2008 22:27
Конкурс*! Хто зможе написати найменший код для копіювання одної char*-стрічки (p) в іншу (q) на С++?
Чим менший код - тим менша оцінка.
В кого найменша оцінка - той переможець!

*Призи переможцям не надаються :)
Надіслати приватне повідомлення
Автор RE: С++
Oracle
Користувач

Повідомлень: 75
Звідки: LNU FAMI-13
Зареєстрований: 20.02.07
Опубліковано 13-06-2008 10:19
XIII написав:
Конкурс*! Хто зможе написати найменший код для копіювання одної char*-стрічки (p) в іншу (q) на С++?
Чим менший код - тим менша оцінка.
В кого найменша оцінка - той переможець!

*Призи переможцям не надаються :)

strcpy(q,p); ;)
_Oracle 492-581-744 Oracle[Lviv NU] Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 14-06-2008 18:30
Ха-ха! А де #include?
Без стандартних функцій!
Надіслати приватне повідомлення
Автор RE: С++
Oracle
Користувач

Повідомлень: 75
Звідки: LNU FAMI-13
Зареєстрований: 20.02.07
Опубліковано 14-06-2008 22:49
ну тоді мінімум на що я спромігся це:
for (int i=0;p[i];) q[i]=p[i++];



П.С. тут вважається що q достатньо велика щоб вмістити p і заповнена нульовими символами.
Змінив(ла) Oracle, 14-06-2008 22:59
_Oracle 492-581-744 Oracle[Lviv NU] Надіслати приватне повідомлення
Автор RE: С++
DixonD
Модератор

Повідомлень: 167
Звідки: ЛНУ ім. Івана Франка
Зареєстрований: 21.10.06
Опубліковано 16-06-2008 08:15
До речі, на рахунок Delphi і dll. З власного досвіду можу сказати, що краще використовувати динамічне звязування замість статичного, тобто використовувати LoadLibrary. Просто якщо якісь проблеми з dll-кою, то наведеному вище використанні тупо не запуститься цілий проект, а так просто не буде працювати лише код, який юзає ту бібліотеку. Кусок коду з реальної проги:
unit Maps;

interface
uses Windows,SysUtils,Forms,Dialogs;

var

NewMSIMap:function :integer; cdecl;

//..............


implementation
var
LibraryHandle:integer;

//..............

initialization

LibraryHandle:=LoadLibraryA(PAnsiChar(ExtractFileDir(Application.ExeName)+'\maps.dll'));
if (LibraryHandle=0) then ShowMessage('Помилка при спробі завантаження maps.dll');
@NewMSIMap:=GetProcAddress(LibraryHandle,PAnsiChar('NewMSIMap'));

//..............

finalization
FreeLibrary(LibraryHandle);
end.




Змінив(ла) DixonD, 16-06-2008 08:16
DixonD 427265719 dixond[злий_пес]acm[на]lviv[на]ua DixonD (Lviv NU) http://dixond.blogspot.com/ Надіслати приватне повідомлення
Автор RE: С++
BlaXpirit
Користувач

Аватар користувача

Повідомлень: 20
Звідки: ЛФМЛ
Зареєстрований: 26.01.08
Опубліковано 26-06-2008 17:41
Oracle написав:
ну тоді мінімум на що я спромігся це:
for (int i=0;p[i];) q[i]=p[i++];



П.С. тут вважається що q достатньо велика щоб вмістити p і заповнена нульовими символами.


Оцінка 30
Тільки чому q має бути заповнена '\0' ?

Ну, добре, дам підказку. А якщо скористатися вказівниками*? *pointer
Змінив(ла) BlaXpirit, 27-06-2008 11:37
Надіслати приватне повідомлення
Перейти на форум:
Голосування
Що Ви б хотіли отримати в якості подарунку на змаганні з програмування?

Медалі

настільні ігри

торт

клавіатура, навушники, флешки і т.д.

квитки в кіно

квитки в аквапарк

квитки на пейнтбол

книги

футболки з логотипом змагання

Для участі в голосуваннях Ви повинні залогуватись.
Міні-чат +
Зараз на сайті -
Гостей: 2
На сайті немає зареєстрованних користувачів

Користувачів: 5,103
новачок: NataEvgten
Powered by PHP-Fusion © 2003-2006
LNU ACMania © 2004-2011 e-mail: webmaster@acm.lviv.ua
26,040,753 унікальних відвідувачів
Our projects: ACM Contester, _College.