NO

Author Topic: reanimate a perished fish  (Read 36595 times)

czerny

  • Guest
Re: reanimate a perished fish
« Reply #15 on: March 05, 2013, 09:56:22 PM »
Quote
Use that MIDL msado15.h and msado15_i.c for GUID/IID.

Yes, this works ok!

There is only one

#endif !_MIDL_USE_GUIDDEF_

which has to be changed to

#endif // !_MIDL_USE_GUIDDEF_

So, what can we say? Is the midl way the canonical way?
What are the two other files (msado15_p.c and dlldata.c) for?

czerny
« Last Edit: March 06, 2013, 01:01:19 AM by czerny »

czerny

  • Guest
Re: reanimate a perished fish
« Reply #16 on: March 06, 2013, 12:04:01 AM »
Can someone please explane? What is the difference between
Connection, _Connection and Connection15 (maybe there are more variants)?
There is a 'struct ADOConnection' too.
I guess there is 'typedef struct ADOConnection Connection;'?

czerny

czerny

  • Guest
Re: reanimate a perished fish
« Reply #17 on: March 06, 2013, 01:06:13 AM »
BTW: In John's site there is ADO with C example:
http://www.johnfindlay.plus.com/lcc-win32/DataBase/c_ado.zip

Thank you! That is a good example.

I haven't jet understand the meaning of INITGUID.
In the above example I found:

/* We define INITGUID so that guids are obtained from the header files
 * instead of a library. Note adoid.h should be included before msado15.h */
/*

What are the pros and cons of using a lib over header files?

czerny

  • Guest
Re: reanimate a perished fish
« Reply #18 on: March 24, 2013, 10:25:04 PM »
Hi,

Quote
In my opinion there are two shortages in Pelles C, the lack of a good library (such as STL)

in the last weeks I have tried to find a good library. In the moment I am exploring 'c2lib'. It is a unix library and propably not trivial to port. But beside that, it uses an own memory mangement, a pool, which is meant for long living objects. The pool is allocated before main
and freed after exit. I am a little bit confused about that. I thought that under modern operating systems like windows or unix a process has its own memory space which is freed by the os. So such an idea like a pool is needless.

What do you thinck about this?

czerny

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #19 on: March 24, 2013, 11:06:23 PM »
A pool (or better: a circular buffer) makes sense for getting quickly small amounts of memory, e.g. for a conversion routine with a tight innermost loop. HeapAlloc is the official recommendation for that, but it's pretty slow (albeit faster than VirtualAlloc).

And it is correct that the OS is supposed to release all memory on ExitProcess, but I have often seen extremely sluggish behaviour well after ExitProcess. Google is not helpful, my best guess is that the OS takes time to zero the released physical memory so that it becomes available to other processes.

czerny

  • Guest
Re: reanimate a perished fish
« Reply #20 on: March 27, 2013, 12:12:32 PM »
A pool (or better: a circular buffer) makes sense for getting quickly small amounts of memory, e.g. for a conversion routine with a tight innermost loop. HeapAlloc is the official recommendation for that, but it's pretty slow (albeit faster than VirtualAlloc).
How can a circular buffer be used to do that? As I understand it, allocs and frees have to arrive in corresponding order, what can not guaranteed.

I have made a little excerpt from the pool implementation of c2lib, just to get the idea. In the original there is much more.

Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #21 on: March 27, 2013, 03:27:30 PM »
A pool (or better: a circular buffer) makes sense for getting quickly small amounts of memory, e.g. for a conversion routine with a tight innermost loop. HeapAlloc is the official recommendation for that, but it's pretty slow (albeit faster than VirtualAlloc).
How can a circular buffer be used to do that? As I understand it, allocs and frees have to arrive in corresponding order, what can not guaranteed.

You simply don't free them. A circular buffer is meant to get a temporary storage, e.g. a MAX_PATH buffer used in a string concatenation, a conversion, etc. The sequence is roughly:

0. Allocate a fat buffer (fat=somewhere below your data cache size)

repeat
  1. ask the slot manager for a pointer to the next free slot
  2. write to that buffer (up to some maxbytes setting)
  3. store ptr and bytes written to your private variables
  4. inform the slot manager about the end of your slot
  5. slot manager adds a few bytes, aligns the pointer and waits for the next request
until end of program

x. Free the fat buffer

czerny

  • Guest
Re: reanimate a perished fish
« Reply #22 on: March 27, 2013, 06:25:04 PM »
You simply don't free them. A circular buffer is meant to get a temporary storage, e.g. a MAX_PATH buffer used in a string concatenation, a conversion, etc. The sequence is roughly:

0. Allocate a fat buffer (fat=somewhere below your data cache size)

repeat
  1. ask the slot manager for a pointer to the next free slot
  2. write to that buffer (up to some maxbytes setting)
  3. store ptr and bytes written to your private variables
  4. inform the slot manager about the end of your slot
  5. slot manager adds a few bytes, aligns the pointer and waits for the next request
until end of program

x. Free the fat buffer

What do you mean with: 3. store ptr

A pointer to this location is useless. It gets overwritten by further requests.

What do you mean with: 3. store bytes

If you copy your data, the location is not longer needed and a job manager is jobless.


Offline jj2007

  • Member
  • *
  • Posts: 536
Re: reanimate a perished fish
« Reply #23 on: March 27, 2013, 07:48:50 PM »

What do you mean with: 3. store ptr

A pointer to this location is useless. It gets overwritten by further requests.

What do you mean with: 3. store bytes

If you copy your data, the location is not longer needed and a job manager is jobless.

store pointer means assign it to some variable.
store bytes means use another variable to keep the length of memory used.

There are many instances where you need storage only temporarily. Example string concatenation (sorry for the Basic syntax):

Print "Today is the ", Left$(Date$,6), ", and it is ", Left$(Time$, 5), CrLf$, "and the name of this file is ", CL$(0), CrLf$

Output:
Today is the 27.03., and it is 19:37
and the name of this file is C:\Masm32\test.exe

Date$, Time$ and CL$() use all a different fraction of the fat buffer, because the slot pointer advances.
Below the Print line, the memory is no longer needed. Still, it does not get overwritten in this moment, but rather after another 1000+ lines of such code, when the slot pointer restarts from the beginning of the fat buffer.

This is not for permanent global memory, but within the scope of a procedure it is perfectly feasible and safe, and about a factor 1000 faster than HeapAlloc/HeapFree pairs. I use it a lot, actually.

But it's not the same as a full-fledged memory manager, of course.

czerny

  • Guest
Re: reanimate a perished fish
« Reply #24 on: March 28, 2013, 12:29:00 PM »
Ok, I want to describe one way to use a COM library (ADO in this example).

This way uses midl.exe, so the PSDK has to be installed.

1. create an empty directory, say 'test'
2. in the directory 'test' invoke 'midl msado15.idl'
3. copy the files 'msado15_i.c' and 'msado15.h' to your project
4. browse the header file for the available interfaces and use that

modifyed example from timovjl:
Code: [Select]
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wchar.h>
#include <ole2.h>
#include <stdio.h>
#include "msado15.h"

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "oleaut32.lib")

WCHAR *szAppName = L"MSADOTest";

int main(int argc, char **argv)
{
HRESULT hr;
//_Connection *pConn = NULL;
Connection15 *pConn = NULL;

hr = CoInitialize(NULL);
//hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_ALL, &IID__Connection, (void **)&pConn);
hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_ALL, &IID_Connection15, (void **)&pConn);
if (hr)
MessageBox(0, L"Error CoGetClassObject()", szAppName, 0);
else
{
// STDMETHOD(Open)(THIS,BSTR,BSTR,BSTR,LONG);
//hr = pConn->lpVtbl->Open(pConn, NULL, NULL, NULL, -1);
//hr = pConn->lpVtbl->Open(pConn, L"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb;", NULL, NULL, -1);
hr = pConn->lpVtbl->Open(pConn, L"Driver={Microsoft Access Driver (*.mdb)};Dbq=test.mdb;", NULL, NULL, -1);
if (!hr)
{
LONG nState;
pConn->lpVtbl->get_State(pConn, &nState);
pConn->lpVtbl->Close(pConn);
wprintf(L"nState = %d\n", nState);
}
else wprintf(L"Error in Open() : %Xh\n", hr);

pConn->lpVtbl->Release(pConn);
pConn = NULL;
}
CoUninitialize();
return 0;
}

You have to create an empty database 'test.mdb' to use the example.
As you can see: you have not to deal with UUIDs and you have not to define INITGUID nor to include <guiddef.h>.
That's all handeled by 'msado15_i.c'.

In the above example both interfaces '_Connection' and 'Connection15' are working. I don't know the difference.
There are also two different connection strings which also both are working.

The header file 'msado15.h' is to big for the ide.

It would be nice, if some people could try these steps and report.

czerny
« Last Edit: March 28, 2013, 12:37:59 PM by czerny »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: reanimate a perished fish
« Reply #25 on: March 28, 2013, 01:36:25 PM »
Here is empty test.mdb for testing.
Quote
In the above example both interfaces '_Connection' and 'Connection15' are working. I don't know the difference
Look at msado15.h, Connection15 is for older version 1.5 level.
May the source be with you

czerny

  • Guest
Re: reanimate a perished fish
« Reply #26 on: March 29, 2013, 08:13:30 PM »
timovjl! Here is the testproject.

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: reanimate a perished fish
« Reply #27 on: March 30, 2013, 08:19:21 AM »
In msado15.h Connection15 first interface method after Invoke should be
STDMETHOD(get_Properties)(THIS,Properties **);
It is inherited from _ADO
_Connection is inherited from _ADO and Connection15 (use OleView to look at)
and last method is
STDMETHOD(Cancel)(THIS);

After you copy corrected Connection15 to _Connection you can use it too.
Any experts to confirm this ???

New example in ADOTest4.zip using msado20.h generated from msado20.tlb
« Last Edit: March 31, 2013, 12:21:06 PM by timovjl »
May the source be with you

czerny

  • Guest
Re: reanimate a perished fish
« Reply #28 on: March 30, 2013, 01:28:42 PM »
Timovjl,

ComTypeLibList produces an empty declaration with 'msado15.dll':
Code: [Select]
#undef INTERFACE
#define INTERFACE ADOConnectionConstruction
DECLARE_INTERFACE(ADOConnectionConstruction) {
/* IUnknown methods */
};

#ifdef COBJMACROS
#endif /* COBJMACROS */
now the header file is much longer. It's very difficult to understand, what you have changed (and way).
« Last Edit: March 30, 2013, 01:30:22 PM by czerny »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: reanimate a perished fish
« Reply #29 on: March 30, 2013, 01:43:07 PM »
now the header file is much longer.
Convert that file to ANSI, that program generate UNICODE file.
Quote
It's very difficult to understand, what you have changed (and way).
Modified ComTypeLibWorker code generate that header.

Quote
ComTypeLibList produces an empty declaration with 'msado15.dll':
Just comment that out.

This is missing from that generated header msado15.h
Code: [Select]
#ifdef _WIN64
typedef LONGLONG ADO_LONGPTR;
#else
typedef LONG ADO_LONGPTR;
#endif
Error code list: http://support.microsoft.com/kb/209050
« Last Edit: March 30, 2013, 02:20:37 PM by timovjl »
May the source be with you