NeroApi + C++ Builder 6 (important)

vbimport

#1

Hello
I have a problem with NeroApi and using it in C++ Builder.
C++ Builder is not compatible with NeroApiGlue and I must
use only NeroApi.dll
I’m loading this library and getting addresses of Nero functions and all is ok. Later I initialize Nero api by calling NeroInit and the result is NEROAPI_INIT_OK, but when I calling NeroGetAvailableDrivesEx i get pointer to device infos where nsdisNumDevInfos is 3 and it is still good but the nsdisDevInfos[]information is good only for first drive (ImageRecorder).
Does someone have any idea for resolve this problem?
I ma using NeroApi in 5.5.8.0 version but 6.3.x.x not working too.
NeroCmd --listdrives shows good values for every of 3 drives.

bhk

P.S.
Sorry for my English :wink:


#2

I have a problem with NeroApi and using it in C++ Builder.
C++ Builder is not compatible with NeroApiGlue and I must
use only NeroApi.dll

NeroAPIGlue is not only for loading the library and getting addresses of the Nero methods. It also does some initialization and cares about compatibility with older NeroAPI versions. So I strongly recommend to not use only NeroAPI.dll.

What’s the problem with C++ Builder and NeroAPIGlue?


#3

I have many problems with C++ Builder and Nero SDK.
Builder doestn’t import all classes from NeroCOM (for example NeroDrive, NeroDrives ) and I can’t use any events from they etc.

I know that NeroApiGlue is a good way to use NeroApi but NeroApiGlue is distributed only as NeroApiGlue.lib (not a dll) and this lib is not compatible with C++ Builder. NeroApiGlue.lib is a COFF type and I must to have OMF. Borland gives a tool to convert COFF lib’s to OMF but it is not working with all files. And with NeroApiGlue not working too.

bhk


#4

Originally posted by bhk
…when I calling NeroGetAvailableDrivesEx i get pointer to device infos where nsdisNumDevInfos is 3 and it is still good but the nsdisDevInfos[] information is good only for first drive (ImageRecorder).

Hello everybody -

I have the same problem as bhk: I get the right number of drives, including the image recorder, and any but the first drive description is data rubbish - the only meaningful member variable is nsdiDeviceName, which is always NDE_DRIVE_IN_USE.

I have tested this on various machines with various drives.
On all of these machines the neroFiddles example just works great (showing the expected drive information). I tested with Nero versions 5.5.10.50 and 6.0.0.23 and it was always the same.

But I use VS.NET, not C++ Builder, and can link to the NeroAPIGlue lib.

My NeroAPI initialization code was simply copy-pasted from the neroFiddles example, so I am currently out of ideas about what I’m doing wrong.
I played around with the include order of the NeroAPI include files, even linked to NeroAPIGlueRT.lib instead of NeroAPIGlue.lib (what is NeroAPIGlueRT.lib for anyway?), but nothing helped.

Maybe anybody else has encountered this problem and found a solution, or at least can contribute ideas or experiences with related problems. Thanks.

Guido


#5

Hi bhk,

I found a “solution” for our problem. After having a close look at the memory area of the returned NERO_SCSI_DEVICE_INFO object I saw a strange 3-byte shift starting from the nsdiDriveLetter member. I changed the type of the member in NeroAPI.h from char to char[4] and, believe it or not, it works!
Even the nsdiReadSpeeds and nsdiWriteSpeeds members suddenly have meaningful values!

The same solution worked for the NERO_CD_INFO structure (that seemed to be corrupted as well); I changed the sizes of the ncdiArtist and ncdiTitle member from 65 to 66 and the size of the ncdiReserved array from 29 to 28, and suddenly everything dropped into the right place.

The modified structures look as follows:


typedef struct tag_NERO_SCSI_DEVICE_INFO
{
char                nsdiDeviceName[64];
char                nsdiHostAdapterName[8];
DWORD               nsdiHostAdapterNo; 
DWORD               nsdiDeviceID;
NEROAPI_SCSI_DEVTYPE nsdiDevType;
char                nsdiDriveLetter[4]; //changed from char to char[4]
DWORD		nsdiCapabilities; 
//...
DWORD               nsdiReserved[62];
} NERO_SCSI_DEVICE_INFO;


typedef struct tag_NERO_CD_INFO
{
DWORD            ncdiFreeCapacityInBlocks;
BOOL             ncdiIsWriteable;
NERO_MEDIUM_TYPE ncdiMediumType;
char             ncdiArtist[66]; // changed from 65 to 66
char             ncdiTitle[66];  // changed from 65 to 66
DWORD		 ncdiAvailableEraseModes;
DWORD		 ncdiUnusedBlocks;		
NERO_MEDIA_TYPE	 ncdiMediaType;		
DWORD            ncdiReserved[28]; // changed from 29 to 28	
DWORD            ncdiNumTracks;
NERO_TRACK_INFO  ncdiTrackInfos[1];
} NERO_CD_INFO;

I did not look for differences in the other structures returned by the Nero functions.

:bow: Dear people at Ahead, please tell me if you have any idea what is happening here! I am especially confused about the fact that neroFiddles works fine with a different header file!

Have a nice weekend!

Looking forward to any replies,

Guido


#6

The core of the problem is the difference in packing alignment for structure members between BCB and MSVC. The former uses the default of 4 and the latter 8. Your particular project seems to have a packing alignment of 1 and this is causing the problem.

You should do the following:


#pragma pack(push, 8)
#include "NeroAPI.h"
#pragma pack(pop)

This will force a packing alignment of 8 for NeroAPI.h and restore it afterwards.


#7

Hi alexp,

you are completely right, your solution works all fine!
Thank you very much!! :bigsmile:

Regards,
Guido


#8

Thanks all for any suggestion.

Thanks GuSi for your solution with changing driveLetter type from char to char[4];
I think that problem isn’t in this place but I found that Builder treats enum type to one-byte object. It should be 4 bytes. I found compiler options which make good it.
If someone have the same problem must check “Treat enum types as ints” in Project->Options->Compiler window.

Alexp your solution:

#pragma pack(push, 8)
#include “NeroAPI.h”
#pragma pack(pop)

doesn’t work in my program.
Thanks all for any suggestion


#9

I think, I know now what the problem is:
You should use NeroSetExpectedAPIVersion(Ex) to set the API version with which you application was compiled:


Using this function, an application can tell NeroAPI for which version of NeroAPI it was
designed to work. NeroAPI will then try to behave as this version as much as possible. This
ensures the binary compatibility with future versions of NeroAPI. If this function is not called,
NeroAPI will behaves as NeroAPI 5.0.3.9. If your application uses NeroAPIGlue, this function
will be automatically called. Extended in NeroAPI 5.5.9.9 to support multiple digits 

But as the comment says: This is to maintain compability with future versions. If you compile with NeroSDK 1.04 and do not use the NeroAPIGlue.lib you might become trouble, if your application is used with an older version.


#10

Matze,
You don’t remember my problem but thanks.
I think that today it’s not a problem becouse I probably find solution.

  • I cannot using NeroAPIGlue.lib becouse it is incompatible with COFF libraries which use C++ Builder
  • I’m using NeroApi.dll indirect
  • I’m using NeroSetExpectedAPIVersionEx

I have had a problems becouse C++ Builder sometimes (when it is posibble) packing enum types to smaller type than int, for example in NERO_SCSI_DEVICE_INFOS structure nsdiDevType was packed as 1-byte.

To repair this problem in C++ Builder I must check “Treats enum types as ints” in Compiler options or use:

//align data to 8 bytes blocks
#pragma pack(push, 8)
// treats enum types as integer
#pragma option push -b

in unit which using NeroApi and providing Nero structures