|
How are the C items exported?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
real vinalla statement __declspec(dllexport) int func(...,)
this probelm has to do with mixed language import/export C/C++
But then again I am sure they DLL's written in other Languages e.g. VB wich use C/C++ DLL's
so what I doing is not that uncommon
However part of the problem is that I am including the same Headers in both the C/C++
So ......
If have gotten rid of most of the errors with the exception of some unresolved externs with a prefix of __imp
Which I understand the compiler appends to a C export When the Link of C++ reads the .Lib
generated by the linker of the C proj it cann't seem to match __imp_func
maybee I need to qualify the C DLL EXPORT (___imp_func ) wih something like __cdecl to make it drop the __imp
prefix
Dont know ???
thankx
|
|
|
|
|
I think you can drop the ___imp_func specifier and use standard __declspec(dllexport) .
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
the __imp is generated by the compiler for DLL EXPORTS on a C build
Linking the C++ projects with .lib from C gives me the problem
|
|
|
|
|
ForNow wrote: However part of the problem is that I am including the same Headers in both the C/C++
That's what you should be doing IMO. Then you only make changes in one place.
How are you handling the dllimport/dllexport difference depending on the type
of module being built...with a macro?
You should be able to form your shared header something like this:
#ifdef MY_DLL_BUILD
#define MY_IMPORTEXPORT __declspec(dllexport)
#else
#define MY_IMPORTEXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
MY_IMPORTEXPORT void SomeFunction();
#ifdef __cplusplus
}
#endif
Note that's a simplified solution. You may need more for certain
types of builds.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
coding that seems more stright foward I'll try it tommorow nite
thankx
|
|
|
|
|
According to MSDN, the default constructor for a GDI+ RectF class will initialize the X and Y members to zero. It doesn't say anything about the Width and Height members. Does anyone know if the Width and Height get set to zero? I did some quick testing and it appears so but I thought I'd ask around before relying on this possibility in case I was getting fooled somehow.
From MSDN:
******************************
RectF::RectF Constructor
Creates a RectF object and initializes the X and Y data members to zero. This is the default constructor.
|
|
|
|
|
Here's the source code...
RectF()
{
X = Y = Width = Height = 0.0f;
}
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Where'd you find that?
Is that in the header?
|
|
|
|
|
Oops, by the way...thanks
|
|
|
|
|
Heh I just traced into it in the debugger....it was quicker
at the moment then a text search. And yes, it's in the header...
gdiplustypes.h. Looks like the entire class is inline methods.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I see it now.
Boy I feel stupid.
Thanks for the guidance.
|
|
|
|
|
Hi All,
I am looking some code in a dll which is part of a project I inherited & see the following code in a CWinThread derived class:
<br />
BOOL CMyThread::InitInstance()<br />
{<br />
AfxEnableControlContainer();<br />
AfxOleInit();<br />
<br />
CoInitialize(NULL);<br />
<br />
AFX_MANAGE_STATE(AfxGetStaticModuleState());<br />
<br />
return TRUE;<br />
}<br />
Is it me, or does AFX_MANAGE_STATE() not belong here? The thread is instantiated from other plaes in code where AFX_MANAGE_STATE has already been called & there is no cross-thread communication w/ other threads or the calling process.
Is it common practice to call AFX_MANAGE_STATE from a CWinThread derived class's InitInstance() ?
Also, does it matter if I call CoInitialize/CoInitializeEx before calls to AfxEnableControlContainer()/AfxOleInit()?
Thanks!
|
|
|
|
|
Wes Jones wrote: Is it common practice to call AFX_MANAGE_STATE from a CWinThread derived class's InitInstance() ?
Only if the place in which it is called will be loading resources from the DLL.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hmm.. so if the InitInstance brought up a CDialog based class & called DoModal(), it'd be loading resources & it'd be a good idea to call this?
such as:
<br />
viod MyDll_ShowScreen()<br />
{<br />
AFX_MANAGE_STATE(...);
...<br />
AfxBeginThread( RUNTIME_CLASS(CMyThread) );<br />
}<br />
<br />
CMyThread::InitInstance()<br />
{<br />
AFX_MANAGE_STATE(....);
<br />
CMyDlg dlg(...);<br />
dlg.DoModal();<br />
<br />
PostThreadMessage(WM_QUIT,0,0);<br />
return TRUE;<br />
}<br />
<br />
MyDll_ShowScreen();<br />
|
|
|
|
|
Yes, otherwise the InitInstance() method would be looking for CMyDlg 's dialog template in the EXE that owns your DLL.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
My understanding is that AFX_MANAGE_STATE is it's on more of a module level, not so much on a per-thread level.
|
|
|
|
|
Wes Jones wrote: does it matter if I call CoInitialize/CoInitializeEx before calls to AfxEnableControlContainer()/AfxOleInit()?
CoInitialize(Ex), if needed, should be called before AfxOleInit().
I don't know if this note from the docs is relevant here...
"If AfxOleInit is called from an MFC DLL, the call will fail. The failure
occurs because the function assumes that, if it is called from a DLL, the
OLE system was previously initialized by the calling application."
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Isn't DLLMain() a more appropriate place for initialization calls. Doesn't the documentation even say that? I have always initialized OLE and cleaned it up in DLLMain for DLL_THREAD_ATTACH/DLL_PROCESS_ATTACH and DLL_THREAD_DETACH/DLL_PROCESS_DETACH and have never had any problems.
led mike
|
|
|
|
|
hmm I thought one wasn't supposed to call any ole init funcs from dllmain.
Maybe this is irrelevant, but from the docs:
"Because there is no way to control the order in which in-process servers
are loaded or unloaded, do not call CoInitialize, CoInitializeEx, or
CoUninitialize from the DllMain function."
What thread is DllMain called on? Does it even make sense there? I dunno...
my brain is fried today (death in family...nightmare week).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
in-process servers, hmm, I would like to see more of that. Do you have a link? I was not thinking about COM servers but just DLL's as it has been many years since I have developed any COM servers. I guess my recent experience has limited my thinking *that's weak*. In the recent past my DLL models have been for libraries that use COM servers rather than implementing them. I have never had a problem even though multiple init's are surely happening within the process.
Mark Salsbery wrote: What thread is DllMain called on?
The current process is creating a new thread. When this occurs, the system calls the entry-point function of all DLLs currently attached to the process. The call is made in the context of the new thread.
link[^]
led mike
|
|
|
|
|
led mike wrote: I would like to see more of that. Do you have a link?
CoInitializeEx()[^] - Remarks, last line.
That's why I said it might be irrelevant to this case....maybe that just applies to COM servers.
Thanks for the link about the DllMain thread! I was just reading that
Mark
*EDIT* OOps - fixed the post LOL
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I did follow the code into AfxOleInit(), & since it's in the context of a DLL, it just sets a variable to -1 & returns TRUE w/out really doing anything. It assumes calling process as initialized OLE.
|
|
|
|
|
Cool. Thanks for the update!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi i had posted this before too i have and image acquisition code that acquires image from CCD camera and stores it to pointer named "*memory"
pl_exp_start_seq(hCam, memory)
i want to display this memory as bmp file and save it to my hard disk, i did write code for it but that saves it in 8 bit format and i loose a lot of valuable information can any one please help, y code is as follows and thankz in advance
void Create_DIB( HWND hWnd )
{
HDC hDC;
unsigned char i;
long k,j, NumBytes;
LPBITMAPINFO info;
unsigned char *dat;
DWORD error;
hDC = GetDC (hWnd) ;
// Intialize BITMAPINFOHEADER data.
//.................................
bi.biSize = sizeof (BITMAPINFOHEADER) ;
bi.biWidth = W;
bi.biHeight = -H; // top-down DIB
bi.biPlanes = 1;
bi.biBitCount = COLORBITS;
bi.biCompression = BI_RGB;
bi.biSizeImage = ( ALIGNLONG( (W * COLORBITS)/8 ) * H);
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 256;
bi.biClrImportant = 256;
// Allocate memory for BITMAPINFO structure.
//..........................................
NumBytes = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD); // +
//( ALIGNLONG( ( W * COLORBITS ) / 8 ) * H );
lpbi = (BITMAPINFOHEADER*)GlobalAlloc( GPTR, NumBytes );
if( lpbi == NULL )
{
LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL );
// Display the string.
MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
exit( EXIT_FAILURE ); // Get out now!
}
// Copy BITMAPINFOHEADER information.
//...................................
*lpbi = bi;
// Create The Palette
info = (LPBITMAPINFO) lpbi;
for ( i=0; i<255; i++ )
{
info->bmiColors[i].rgbRed = i;
info->bmiColors[i].rgbBlue = i;
info->bmiColors[i].rgbGreen = i;
info->bmiColors[i].rgbReserved = 0;
}
// Set pointer to bitmap’s bit data.
//..................................
// lpstBitmap = (LPSTR)lpbi + (WORD)sizeof(BITMAPINFOHEADER) +
// (256 * sizeof(RGBQUAD));
hBitmap = ::CreateDIBSection(hDC,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS,(VOID **)&lpstBitmap, NULL,0);
dat = (unsigned char*)lpstBitmap;
for ( k=0; k< H; k++ )
for ( j = 0; j < W; j++ )
*dat++ = (unsigned char)k;
// Create uninitialized DIB bitmap.
//.................................
/* hBitmap = CreateDIBitmap( hDC,
&bi,
0 ,
0,
(LPBITMAPINFO) lpbi, */
error = GetLastError();
ReleaseDC( hWnd, hDC);
}
void Save(int num)
{
CString prefix = "C:\\Documents and Settings\\Garner Lab\\My Documents\\Xanoscopeimages\\image";
char buf[4];
itoa(num, buf, 10);
CString number = buf;
CString suffix = ".bmp";
fullname = prefix + number + suffix;
CImage image;
image.Attach(hBitmap);
image.Save(fullname); // save as BMP
image.Detach();
|
|
|
|