overloading DcmQueryRetrieveConfig Class

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
Monteaup
Posts: 3
Joined: Fri, 2010-10-15, 10:34

overloading DcmQueryRetrieveConfig Class

#1 Post by Monteaup »

Hallo,

I have implemented a new DBHandle for DCM Query/Retrieve. Now I would like to use a alternative configuration fileformat.
I don't see a way to overload the DcmQueryRetrieveConfig Class for this purpose because the configuration parameters are private...

I'm also not able to replace this class, because DcmQueryRetrieveSCP is also using this class and probably other as well.

regards,
Martin.

Michael Onken
DCMTK Developer
Posts: 2054
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#2 Post by Michael Onken »

Hi Martin,

at the moment I would say: Derive from it and overwrite all public interface methods.

As far as I can see (never looked deeply into dcmqrdb), it would make most sense to take over the public methods into an abstract base class (e. g. as DcmQueryRetrieveConfig) and then derive one for the file-based config (e. g. DcmQueryRetrieveFileConfig, containing the current implementation for files) and one (e.g. DcmQueryRetrieveSQLConfig) containing an SQL implementation of that interface. Is this what you are thinking of?

Best regards,
Michael

Monteaup
Posts: 3
Joined: Fri, 2010-10-15, 10:34

#3 Post by Monteaup »

Hallo Michael.

No, I don't think so... I would like to replace completely the current configuration file because my configuration tool can't handle this files.

Overwriting all public methods does not help, because all configuration parameters are private. I can't store the parameters loaded by my overloaded method.

regards,
Martin.

Michael Onken
DCMTK Developer
Posts: 2054
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#4 Post by Michael Onken »

Hi,

maybe you got me wrong. Why not just have a classes like that:

Code: Select all

// Only abstract base class (interface)
class DcmQueryRetrieveConfig {

public:

  peerForAETitle(..) =0;
  getMaxStudies(..) =0;
   ...
};

Code: Select all

class DcmQueryRetrieveFileConfig : public DcmQueryRetrieveConfig  {

public:

  peerForAETitle(..);
  getMaxStudies(..);
   ...

protected:

  init(const char *ConfigurationFile);
  ...

private:

  // whatever this class needs, e.g. easiest is to take over what is currently in the configuration class.
 // we should _not_ make the members protected, only the interface.
 
};

Code: Select all

class DcmQueryRetrieveDBConfig : public DcmQueryRetrieveConfig  {

public:

  peerForAETitle(..);
  getMaxStudies(..);
   ...

protected:

  OFCondition init(const OFString& dbName,
                          const OFString& user,
                          const OFString& pass);
  ...

private:

  // whatever this class needs
  // we should _not_ make the members protected, only the interface.
  DBHandle *handle;
This permits the rest of the dcmqrdb code to be used as is as long as your configuration class inherits from the abstract base class. For dcmqrscp, one would then create the file configuration class. Not 100% sure it works but I think the most obvious way to do it.

What would be your idea instead, making the members directly protected/public?

Best regards,
Michael

nark
Posts: 8
Joined: Fri, 2009-09-04, 14:15

#5 Post by nark »

Hi,

I dig up this topic because I am in a quite similar situation. I am deriving several classes from the dcmqrdb module to run my own Q/R service building on a SQLite backend. I already achieved this few times ago with dcmtk 2.5.4, by modifying the library itself, what I currently do not want to do because I am in a very strictly UNIX development process.

So, I currently derived three classes which are:

Code: Select all

- DcmQueryRetrieveDatabaseHandleFactory 	> DcmQueryRetrieveSQLiteDatabaseHandleFactory
- DcmQueryRetrieveDatabaseHandle 			> DcmQueryRetrieveSQLiteDatabaseHandle
- DcmQueryRetrieveConfig 					> DcmQueryRetrieveSQLiteConfig
I know that database handle inherited classes should work, but the derivation of the config class is new for me. I derived all public methods of DcmQueryRetrieveConfig to overload their behaviors but it seems that there is a C++ complexity I don't understand.

I made several tests :

- When I only derive public methods from DcmQueryRetrieveConfig without re-declaring private attributes of the parent class, I experienced a segmentation fault.

- If I re-declare few private attributes of the parent class (networkTCPPort_, maxPDUSize_, maxAssociations_ and CNF_config) the segmentation fault is not triggered, but my derived class does not appear to be used.

To be sure, I ran my program into gdb to have a backtrace to see what dcmtk exactly does, and this obviously shows that my derived class is not used by my DcmQueryRetrieveSCP instance:

Code: Select all

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x0000000106efd8c4 in DcmQueryRetrieveConfig::peerInAETitle () at dctagkey.h:259
259	}
(gdb) bt
#0  0x0000000106efd8c4 in DcmQueryRetrieveConfig::peerInAETitle () at dctagkey.h:259
#1  0x0000000106f158c9 in DcmQueryRetrieveSCP::waitForAssociation () at dctagkey.h:259
#2  0x0000000106ca7eec in dp_qrscp_init () at qrscp.cpp:139
#3  0x0000000106ca6d4e in main (argc=1720342168, argv=0x7ff658e00112) at main.cpp:155
I instantiate my DcmQueryRetrieveSCP as follow:

Code: Select all

DcmQueryRetrieveSQLiteConfig config;
config.init(dp_database);
    
DcmQueryRetrieveSQLiteDatabaseHandleFactory factory(dp_database, sPath);
DcmQueryRetrieveSCP * localSCP = NULL;
    
localSCP = new DcmQueryRetrieveSCP(config, options, factory);
I'm not a daily C++ developer (C/Obj-C developer) and I suspect that I am missing something obvious in the derivation process. My intuition says that there is something to do around non-virtual classes derivation and/or implicit casting. Before going further, maybe someone here can confirm that and/or provide a working solution.

I can post more code if needed, let me know…

Best regards,
Nark
Last edited by nark on Sun, 2012-03-04, 16:25, edited 1 time in total.

nark
Posts: 8
Joined: Fri, 2009-09-04, 14:15

#6 Post by nark »

Hm… After googling a bit about CPP derivation and conventions, I found this thread on another forum:
http://www.gamedev.net/topic/333370-c-derivation-issue/

Users there say that a CPP class without a defined default constructor cannot be inherited. The DcmQueryRetrieveConfig does not provide a such method. If I am right, I am really in trouble… And it's embarrassing if the DCMTK design prevents doing that.

I hope to be totally wrong about this design issue and that I missed an obvious key. Maybe someone here can confirm/invalidate my cogitations…

Best regards,
Nark

Michael Onken
DCMTK Developer
Posts: 2054
Joined: Fri, 2004-11-05, 13:47
Location: Oldenburg, Germany
Contact:

#7 Post by Michael Onken »

Hi,

the derivation should not be the problem. Maybe, in your own class, you access members of the base class after they have been freed already there? Or before they are instantiated with meaningful values?
The function "peerInAETitle" seems to be trying to read from a NULL pointer adress, i.e. there is no data initialized. The easiest way to find out should be step-by-step-debugging, maybe set a breakpoint in DcmQueryRetrieveConfig::peerInAETitle().

Best,
Michael

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Semrush [Bot] and 1 guest