вызов DLL, написанной на MSVC++ 6, из VBasic6

irina-sokolov

в функции на С++ пытаюсь передать параметр long.
вызываю из VB функцию с параметром ByVal Long, ByRef Long - один хрен пишет Bad DLL Calling Convention!
ХЕЛП, плиз.

shlyumper

Объяви ее в исходнике на C++ как extern "C", там с именами проблема.

dberezhnoy

Параметры функций COM объявлены через формат данных VARIANT? Если нет, то, видимо, ты не сможешь из VB вызвать эти функции.

irina-sokolov

комов там вообще нет.
Обыкновеная DLL

irina-sokolov

extern "C" помогло только убрать уродские символы в названии функции при импорте (спасибо - Quick Plus можно не пользовать теперь). Вызов по-прежнему не работает.

shlyumper

функция объявлена как extern "C" WINAPI ...?

irina-sokolov

спасибо! после __stdcall заработало.

Crash770909

функция объявлена как extern "C" WINAPI ...?
а какая разница?
не получится ничего
пиши ком с дуальным интерфейсом

shlyumper

Спорим на ящик пива, что получится?
Вот не люблю же я, когда такие голословные и неаргументированные утверждения делают...

irina-sokolov

жаль, поспорить не успел. Так бы пиво поделили
Не подскажешь еще из-за чего из моей DLL другая (не моя) не вызывается. При компиляции моей DLL почему-то про _main линкер ругается.

shlyumper

Вполне возможно, что это связанно с руганью при компиляции. Как и чем ты компилируешь свою dll? У тебя в ней есть специальный main, типа DllMain или _DllMainCRTStartup?

irina-sokolov

DllMain
MSVC++ 6.0

shlyumper

Опции правильно выставил? У тебя именно DLL собирается?
Каким образом пытаешься внешнюю dll вызывать? Как именно "ругается"?

irina-sokolov

собирается именно в длл, поскольку все работает, пока не делаешь вызовы внешней длл.
ругается так:
Linking...
Creating library Debug/testdll.lib and object Debug/testdll.exp
LIBCMTD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/testdll.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
Creating browse info file...
testdll.dll - 2 error(s 9 warning(s)
Подключаю я ее так: скопировал dll, lib, h в директорию, проинклудил h, после чего делаю вызов.
Из exe-шника та же фигня прокатывает (те же вызовы).

shlyumper

Ты это из IDE собираешь, или из командной строки?
Кроме того, судя по ошибке, ожидается вместо DllMain что-то такое:

extern "C" int __stdcall _DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
return 1;
}


Я обычно собираю из своего makefile примерно так:
cl -Zp2 -LD -MD -GX -Zi file1.cpp file2.cpp .... user32.lib kernel32.lib ole32.lib uuid.lib /link /nod:libc

irina-sokolov

собираю из ИДЕ. Заменил DllMain на твою функцию, поменяв ENTRY. Нет изменений.

shlyumper

Проверяй настройки проекта, он где-то у тебя неправильно линкуется. Сейчас попробовал сделать через IDE простенький Win32 dll проект, все собирается без проблем и каких-либо ошибок.

irina-sokolov

проблема как раз в том, что я нихрена в этом не разбираюсь. Я на джаве пишу, а там подобного гемора вообще нет.

irina-sokolov

я и говорю, что если просто функции обыкновенные, то все нормально собирается. А когда вызов есть еще из внешней библиотеки, то облом. Я вот думаю, может это связано как-нибудь с тем, что я хедер инклужу? Хедер внешний адаптировать не надо?

Dasar

> проблема как раз в том, что я нихрена в этом не разбираюсь. Я на джаве пишу, а там подобного гемора вообще нет.
1. Тогда создай через визард еще один простой DLL-проект.
2. Убедись что он компилируется
3. Перенеси в него все свои h и cpp файлы

irina-sokolov

У меня этот старый проект компилится, если внутри кода вызов внешней функции закомментировать.
Мистика какая-то. Это может быть глюк VC++?
Зачем в новый переносить?

Dasar

> Зачем в новый переносить?
Это чтобы было проще локализовать проблему.
Но раз ты проблему уже локализовал (знаешь, что надо закоментировать то не надо.
А как выглядит кусок, который ты комментируешь?

irina-sokolov

//---------хедер
//#define TESTDLL_EXPORTS
#ifdef TESTDLL_EXPORTS
#define TESTDLL_API __declspec(dllexport)
#else
#define TESTDLL_API __declspec(dllimport)
#endif
#include <atlbase.h>
// This class is exported from the testdll.dll
/*class TESTDLL_API CTestdll {
public:
CTestdll(void);
// TODO: add your methods here.
};
*/
//extern TESTDLL_API int nTestdll;
extern "C" {
TESTDLL_API int fnTestdll(void);
TESTDLL_API __stdcall long SignFile(long s);
TESTDLL_API __stdcall int fmy_cr_init(int use_tm, char * gk, char * uz, char * pwd);
}
//-------------С++
#include "stdafx.h"
//#include <afx.h>
#include <stdio.h>
#include <conio.h>
//#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <time.h>
#include <io.h>
#include "testdll.h"
#include "string.h"
#include "bcry.h"
#include "errors.h"
CR_INIT *my_cr_init;
char tm_number[100];
int tm_len;
int mode;
extern "C" int __stdcall _DllMainCRTStartup( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
//TESTDLL_API int nTestdll=0;
// This is an example of an exported function.
TESTDLL_API int fnTestdll(void)
{
return 42;
}

// This is the constructor of a class that has been exported.
// see testdll.h for the class definition
/*CTestdll::CTestdll
{
return;
}
*/
//============================IGOR=============================
/*TESTDLL_API int InitCR(void)
{
int res = 0;
return res;
}*/
TESTDLL_API __stdcall long SignFile(long s)
{/*my_cr_init = NULL;
cr_init(1, //use tm
"gk.db3", "uz.db3",
"",
tm_number, &tm_len,
&mode, &my_cr_init);*/
return (s);
}

TESTDLL_API __stdcall int fmy_cr_init(int use_tm, char * gk, char * uz, char * pwd)
{
//ВОТ ЭТОТ КУСОК
return (cr_init(use_tm, //use tm
gk, uz,
pwd,
tm_number, &tm_len,
&mode, &my_cr_init;
//КОНЕЦ ЭТОГО КУСКА
// return 0;
}

//из хедера внешней библиотеки
//-------------------
#ifndef _B_CRY_H_
#define _B_CRY_H_
#define WIN32
#define DECL __stdcall
/* #ifndef DECL
#ifdef WIN32
#ifdef __BORLANDC__
#define DECL PASCAL __export
#else
#define DECL PASCAL
#endif
#else //WIN32
#define DECL
#endif //WIN32
#endif
*/
#define ERR_NOT_USED_TMDRV 11110
#define ERR_NOT_USED_DSCH 11111
#define ERR_NOT_USED_GKUZ 11112
#define cTMDRV 4
#define cDSCH 2
#define cGKUZ 1
#ifndef CR_ZAG
typedef struct { void *empty; } CR_INIT;
typedef struct { void *empty; } CR_USER;
typedef struct { void *empty; } CR_NET;
typedef struct { void *empty; } CR_BBUF;
typedef struct { void *empty; } CR_PKEY;
typedef struct { void *empty; } CR_PKBASE;
typedef struct { void *empty; } CR_HASH;
//размер заголовка
#define CR_HDR_SIZE 48
#endif
extern "C" {
#ifndef WIN32
// инициализация библиотеки для DOS
int DECL cr_init (int tm_flag, int *init_mode, CR_INIT **init_struct);
#else
// инициализация библиотеки для Windows 95/NT
int DECL cr_init (int tm_flag,
const char *gk,
const char *uz,
const char *psw,
char *tm_number,
int *tmn_blen,
int *init_mode,
CR_INIT **init_struct);
#endif
//...................................
//...................................
}
#endif

freezer

убрать переменную _ATL_MIN_CRT пробовал?

psm-home

Угу. Только _ATL_MIN_CRT не переменная, а препроцессорный define.

freezer

да хоть горшком назови

psm-home

Да, каюсь. Придираюсь в общем-то зря. Главное ты сказал: раз у в проекте использована ATL, то причиной появления проблем с символом _main запросто может быть макрос _ATL_MIN_CRT. Ты-то наверное знаешь про это все, а , возможно, будет интересно узнать. откуда ноги растут и как лечить. Вот по-русски:
RSDN - rulezzz
А вот из первых рук:
MSDN
Может я это зря пишу, но вдруг пригодится.
Оставить комментарий
Имя или ник:
Комментарий: