Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / работа c++builder'овской dll в приложении visual .net / 18 сообщений из 18, страница 1 из 1
07.07.2006, 12:21
    #33837960
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Код: plaintext
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.
32.
33.
34.
int _tmain(int argc, _TCHAR* argv[])
{
	HINSTANCE hinstLib; 
	MYPROC ProcAdd; 
    BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 
     // Get a handle to the DLL module.
 
    hinstLib = LoadLibrary(TEXT("DBConn.dll")); 	
	//HINSTANCE dbc = LoadLibrary();

	//  00001790      1   0041  BDEQuery(std::vector<record, std::allocator<record> > *, const char *, const char *)
	if (hinstLib != NULL) 
    { 
		ProcAdd = (MYPROC)((char*)hinstLib + 0x1790);//GetProcAddress(hinstLib, "BDEQuery"); 
        // If the function address is valid, call the function.
        if (NULL != ProcAdd) 
        {
            fRunTimeLinkSuccess = TRUE;
			std::cout<<"work"; 
			const char* query = "select * from bar.db";// where cardarticul like \'SIXOJ499/9539OO/125\'";
			const char * dbase = "pnshop";
			std::vector<record> res;
			int rest = (*ProcAdd)(&res, query, dbase);
			std::cout<<rest<<'\t';
			if(res.size())
				std::cout<<static_cast<char(*)[16]>(res.front().begin());
        }
        // Free the DLL module.
        fFreeResult = FreeLibrary(hinstLib); 
    // If unable to call the DLL function, use an alternative.
    if (! fRunTimeLinkSuccess) 
        printf("Message via alternative method\n");
	}
	//int test = BDEQuery(&res,query,dbase);
	return  0 ;

сама библиотека подключается - только в путь. адрес же ф-ции получить не могу - все время null. если, как в листинге, указываю ее адрес прямо, то она вызывается, но возвращает рез-т, возникающий в случае программного исключения (-1). при том, что с с++ builder-приложением отрабатывает нормально.

код dll:
Код: plaintext
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#include <vector.h>
#include <iostream>
#include "record.h"
#include <extctrls.hpp>
#include <DBTables.hpp>
#pragma hdrstop
//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
typedef vector<record> v_rec;
typedef vector<char> v_char;

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
	return  1 ;
}
//---------------------------------------------------------------------------

int _export BDEQuery(vector<record>* ptrRes, const char* ptrQry, const char* alias)
{
	TQuery* myQ = new TQuery((TComponent*)NULL);
	myQ->Active = false;
	myQ->DatabaseName = AnsiString(alias);
	myQ->SQL->Clear();
	myQ->SQL->Add(AnsiString(ptrQry));
	myQ->Active = true;
	myQ->First();
	try
	{
	for(int i= 0 ;i<myQ->RecordCount;i++)
	{
		for(int j= 0 ;j<myQ->FieldCount;j++)
		{
			record iter;
			iter.resize(myQ->Fields->operator [](j)->Size);
			myQ->Fields->operator [](j)->GetData(iter.begin(),true);
			ptrRes->push_back(iter);
		}
		myQ->Next();
	}
	myQ->~TQuery();
	return  0 ;
	}
	catch(...)
	{
		return - 1 ;
	}
}
можно ли как-то отследить работу самой dll, чтобы понять, что ей не нравится?
...
Рейтинг: 0 / 0
07.07.2006, 13:34
    #33838260
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
А вы думаете, что MS Visual С++ и Borland C++ Builder используют одинаковую реализацию std::vector ????
А адрес не находится потому, что имя у функции в dll что-то типа BDEQuery$qp33std@%vector$i17std@%allocator$i%%pxct2 (можете Depedncy Walker'ом или чем другим посмотреть).
...
Рейтинг: 0 / 0
07.07.2006, 14:35
    #33838530
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
угу, спасибо. глянул + нашел похожую проблему - лечится либо указанием этих ?@@# и.т.д =))) либо extern "C" приобъявлении. спасибо за помощь
...
Рейтинг: 0 / 0
07.07.2006, 15:15
    #33838681
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Дык, адрес-то вы найдете... А вот передать std::vector в dll собраную другим компилятором скорее всего не получится.
...
Рейтинг: 0 / 0
07.07.2006, 15:43
    #33838786
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
это да, только что наткнулся.
передаю свежесозданный вектор, размер 0 => в dll'ке он уже р-ром под 4мб. в связи с чем это? + а чем можно сие заменить? мне нужен расширяемый массив для передачи данных =/
...
Рейтинг: 0 / 0
07.07.2006, 15:51
    #33838821
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Указатель на адрес памяти и размер.
Для расширения realloc.

или список. Нет необходимости передовать размер, и быстрее расширяться будет.
...
Рейтинг: 0 / 0
07.07.2006, 15:57
    #33838847
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
у меня есть класс record:
record.h
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <malloc.h>

class record
{
	void* ptrData;
	size_t size;

public:
	record();
	record(size_t);

	void*	resize(size_t);
	void*	begin()			{return ptrData;}
	void*	shift(size_t v)	{return (char*)ptrData+v;}
	void*	move(void* iter, size_t v)	{return (char*)iter+v;}
	void*	end()			{return (char*)ptrData+size;}
	size_t	retsize()			{return size;}

	~record();
};
record.cpp
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
#include "record.h"

record::record()
{
	size =  1 ;
	ptrData = malloc(size);
}

record::record(size_t sz)
{
	size = sz;
	ptrData = malloc(size);
}

void* record::resize(size_t sz)
{
	size = sz;
	ptrData = realloc(ptrData, sz);
	return ptrData;
}

record::~record()
{
	free(ptrData);
}

его функционала должно хватить для данной операции?
...
Рейтинг: 0 / 0
07.07.2006, 16:07
    #33838888
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Хватит, т.к. этот класс предоствляет свои данные во внешний мир. В случае необходимости, его можно будт расширить.
...
Рейтинг: 0 / 0
07.07.2006, 16:12
    #33838919
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Вы не сможете передавать между разными компиляторами никакие сложные объекты. Более того, вы не сможете сделать realloc для переданого указателя. Заменить можно только реализацией COM-обекта с нужными методами.
...
Рейтинг: 0 / 0
07.07.2006, 16:25
    #33838969
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
спасибо, попробую ч/з com.
с классом record проблема даже в случае одного компилятора: рез-т запроса должен быть в районе 13мб, меняю ему р-р на требуемый, начинаю закидывать данные:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
	void* iter = ptrRes.begin();
 //	std::vector<record>::iterator it = ptrRes.begin();
//	ptrRes.empty();
	ptrRes.resize(myQ->RecordCount*myQ->RecordSize);
	int Total( 0 );
	try
	{
	for(int i= 0 ;i<myQ->RecordCount;i++)
	{
		for(int j= 0 ;j<myQ->FieldCount;j++)
		{
			iter = ptrRes.move(iter,myQ->Fields->operator [](j)->Size);
			myQ->Fields->operator [](j)->GetData(iter,true);
			Total+=myQ->Fields->operator [](j)->Size;
			std::cout<<"end address: "<<ptrRes.end()<<"\t\tcurrent address: "<<iter<<'\n';
//			std::cout<<myQ->Fields->operator [](j)->AsString.c_str()<<' ';
//			ptrRes.push_back(iter);
//			std::cout<<"\nvector size = "<<ptrRes.size()<<'\n';
		}
		myQ->Next();
		std::cout<<'\n';
	}
в рез-те, когда адрес итератора еще не достиг конечного:
[quote]end address: 7f6ebb61 current address: c8ffd1[/quote]
, он вываливается с access violation.
...
Рейтинг: 0 / 0
07.07.2006, 16:25
    #33838970
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Да, на счет объекта я ошибся. Можно передовать только кусок данных, который нужно будет всунуть в новый объект.

А реаллок будет работать. Если даже он не сможет расширить в текущей области, он создаст в новой и скопирует данные.
...
Рейтинг: 0 / 0
07.07.2006, 16:26
    #33838977
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
BarloneВы не сможете передавать между разными компиляторами никакие сложные объекты... - утверждение folse. см. вызов чужих библиотек. например из клиппера или фортрана - азм. обьектники...

BarloneБолее того, вы не сможете сделать realloc для переданого указателя... - утверждение true.хотя зависит от OS и многих весчей... Если очень категорично - так же мона...

BarloneЗаменить можно только реализацией COM-обекта с нужными методами. - корректней такая формулировка...

Заменить можно реализацией COM-обекта с нужными методами. Даже достаточно применения просто указанной методологии, без оглядки на ось и прочей ерунды...


с уважением
(круглый)
...
Рейтинг: 0 / 0
07.07.2006, 16:35
    #33839008
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
ступил. надо сперва resize, потом уже iter = ptrRes.begin();
...
Рейтинг: 0 / 0
07.07.2006, 16:36
    #33839018
Akh
Akh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
13th_apostle
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
	void* iter = ptrRes.begin();
	ptrRes.resize(myQ->RecordCount*myQ->RecordSize);
	int Total( 0 );
	try
	{
	for(int i= 0 ;i<myQ->RecordCount;i++)
	{
		for(int j= 0 ;j<myQ->FieldCount;j++)
		{
			iter = ptrRes.move(iter,myQ->Fields->operator [](j)->Size);
...
		}
...
	}


1. Выделение памяти производится из расчета, что myQ->RecordSize >= myQ->Fields->operator [](j=1..myQ->FieldCount)->Size. Это верно?
...
Рейтинг: 0 / 0
07.07.2006, 16:38
    #33839033
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
я ступил просто: realloc сохраняет старые данные, но не старый адрес =)
...
Рейтинг: 0 / 0
07.07.2006, 16:53
    #33839117
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
kolobok0 BarloneВы не сможете передавать между разными компиляторами никакие сложные объекты... - утверждение folse. см. вызов чужих библиотек. например из клиппера или фортрана - азм. обьектники...
Я имел ввиду обекты типа std::vector и т.п. Понятно что можно передать любую структуру. А вот с вызовом методов может быть облом (с объектами STL точно будет облом - реализации у borland и ms разные).
kolobok0 BarloneБолее того, вы не сможете сделать realloc для переданого указателя... - утверждение true.хотя зависит от OS и многих весчей... Если очень категорично - так же мона...
Можно, только осторожно... malloc/realloc/free не дергают напрямую функции winapi. Там хранятся списки свободных блоков, устроеные в разных компиляторах по разному. На самом деле всё ещё хуже - даже если и приложение и dll компилируются MSVC, не всегда можно делать например malloc в приложении а free в dll (или наоборот). Можно только если оба используют dynamic runtime library. А если приложение или dll или оба скомпилированы со static runtime library (или используют разные версии msvcrt.dll),то возможен облом в виде периодических GPF.
kolobok0 BarloneЗаменить можно только реализацией COM-обекта с нужными методами. - корректней такая формулировка...
Заменить можно реализацией COM-обекта с нужными методами. Даже достаточно применения просто указанной методологии, без оглядки на ось и прочей ерунды...
с уважением
(круглый)
...
Рейтинг: 0 / 0
07.07.2006, 17:02
    #33839167
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
Да, с классом всё правильно. Если класс реализован в dll, то все malloc/realloc/free будут вызываться из dll. Это должно работать.
...
Рейтинг: 0 / 0
07.07.2006, 17:06
    #33839181
13th_apostle
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
работа c++builder'овской dll в приложении visual .net
BarloneДа, с классом всё правильно. Если класс реализован в dll, то все malloc/realloc/free будут вызываться из dll. Это должно работать.
гмм, объект класса создается в приложении, он по ссылке передается в dll, там realloc, возвращается приложению, из него выцепляются данные, после чего там он и free.

ps. запустил тест - без ошибок, но 13мб он получал оч долго (около 4 мин.). может, есть вариант более быстродействующий? подскажите, плз, куда копать.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / работа c++builder'овской dll в приложении visual .net / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]