Calling indigo C interface from C#

84 views
Skip to first unread message

Kyle Conway

unread,
May 29, 2012, 9:17:05 PM5/29/12
to indigo-...@googlegroups.com
Hi!
 
I'm trying to create an image using indigo and indigo-renderer by calling the C interface from C#. (As a side note, I have used the .NET API which works great on Windows but it won't work on Linux since the code it is compiled against must be Windows specific).
 
I've been able to call the functions to create an image and a file is created, but is's empty! No errors are thrown (from the C# side - I have no idea from the C side). I'm currently just testing it on Windows before trying on Linux (which is why I'm referencing .dll files and not .so files)
 
The smiles string I am passing in for testing is caffeine "CN1C=NC2=C1C(=O)N(C(=O)N2C)C".
 
Here is the code:
        [DllImport("indigo.dll")]
        static extern int indigoLoadMoleculeFromString(string smiles);
        [DllImport("indigo.dll")]
        static extern int indigoLayout(int obj);
        [DllImport("indigo.dll")]
        static extern int indigoSetOption(string name, string value);
        [DllImport("indigo.dll")]
        static extern int indigoSetOptionXY(string name, int x, int y);
        [DllImport("indigo.dll")]
        static extern int indigoFree(int handle);     
        
 
        [DllImport("indigo-renderer.dll")]
        static extern int indigoRender(int obj, int output);
        [DllImport("indigo-renderer.dll")]
        static extern int indigoRenderToFile(int obj, string filename);
 
        public static void StructureFromSMILES(string smiles)
        {             
                int mol = indigoLoadMoleculeFromString(smiles);
                indigoLayout(mol); /*  if not called, will be done automatically by the renderer  */
                indigoSetOption("render-output-format""png");
                indigoSetOption("render-comment""Caffeine");
                indigoSetOption("render-comment-position""top");
                indigoSetOptionXY("render-image-size", 200, 250);             
                
                indigoRenderToFile(mol, "test.png");
         }
Does anyone have any suggestions on what I might be doing wrong?
Thanks!
Kyle Conway

Mikhail Kozhevnikov

unread,
May 31, 2012, 1:45:44 AM5/31/12
to indigo-...@googlegroups.com, conwa...@mail.com
Hi Kyle,

Have you tried doing the same using the Indigo .NET API? Did you get the same result?

Cheers,  
Mikhail

Kyle Conway

unread,
May 31, 2012, 4:19:48 PM5/31/12
to indigo-general
Yes, it works and the file is produced correctly from the .NET API on
Windows. Of course, the .NET API does not work on Linux (actually,
the .NET bit does run on Mono but the native code portion doesn't so
image generation fails).

Kyle

On May 31, 1:45 am, Mikhail Kozhevnikov <kozhevni...@ggasoftware.com>
wrote:

Mikhail Kvyatkovskiy

unread,
Jun 1, 2012, 3:05:00 AM6/1/12
to <indigo-general@googlegroups.com>
Hello Kyle,

I had reproduced this problem. We will try to fix it.

Also I made an experimental port of Indigo .NET API to Mono, it must be possible to use it on Linux and Mac OS X together with Windows. You can try to use it, but it have not been tested well yet, so it might contain some problems. Here is the link to package with universal versions of .NET libraries: http://ggasoftware.com/accept?file=indigo-1.1-rc3%2Findigo-dotnet-1.1-rc3r2-universal.zip

Please let me know if you have any results with it.

Best regards,
Mikhail Kvyatkovskiy, GGA Software.

Mikhail Kvyatkovskiy

unread,
Jun 1, 2012, 6:31:55 AM6/1/12
to <indigo-general@googlegroups.com>
Hello Kyle,

We found what causes your problem. Options from indigo-renderer.dll are registered after the library is loaded. In you code indigo-renderer.dll is loaded when indigoRenderToFile() is called, but renderer options are used before it. That is why indigoSetOption() calls return -1 value instead of 1 is normal case. To fix this problem you need to call any function from IndigoRenderer before setting renderer options, like this:
 public static void StructureFromSMILES(string smiles)
        {             
                int mol = indigoLoadMoleculeFromString(smiles);
                indigoLayout(mol); 
                indigoRenderToFile(mol, "test.png"); // Load indigo-renderer.dll and register its options. Return -1
                indigoSetOption("render-output-format""png"); // Option is set. Return 1                 indigoSetOption("render-comment""Caffeine"); // Option is set. Return 1                 indigoSetOption("render-comment-position""top"); // Option is set. Return 1                 indigoSetOptionXY("render-image-size", 200, 250);  // Option is set. Return 1                                  indigoRenderToFile(mol, "test.png"); // Draw correct picture. Return 1
         }
It might be a good practice to check returned values of functions to find which of them works incorrectly. 

As for Indigo .NET universal package, I found that there are some problems in dll unloading which can produce segmentation fault on Linux, so it might be hard to use it now. We will try to fix them after Indigo 1.1 release. Anyway, your comments about experience of using this package on Mono are very appreciated.

Best regards,
Mikhail Kvyatkovskiy, GGA Software.

Kyle Conway

unread,
Jun 3, 2012, 10:50:46 PM6/3/12
to indigo-general
It works!! Thank you very much for your help! I haven't tried it on
Linux yet but I will tomorrow. I'm confident it will work there too as
all I have to do is change the dll references to the Linux binaries.

I did think of checking the return values. However, as I have never
used C or C++, I wasn't sure that it was going to help me since I'm
familiar with conventions regarding return values.

On a similar topic, as I am very unfamiliar with C and working with it
from C#, I see that images can be output to buffer but not sure if
there is a simple way I could get the image into a C# stream or byte
array (without saving then reopening the file) from the C interface?
Perhaps it is not possible without lots of code.

Thanks again!
Kyle



On Jun 1, 6:31 am, Mikhail Kvyatkovskiy
<mkvyatkovs...@ggasoftware.com> wrote:
> Hello Kyle,
>
> We found what causes your problem. Options from indigo-renderer.dll are registered after the library is loaded. In you code indigo-renderer.dll is loaded when indigoRenderToFile() is called, but renderer options are used before it. That is why indigoSetOption() calls return -1 value instead of 1 is normal case. To fix this problem you need to call any function from IndigoRenderer before setting renderer options, like this:
>
>  public static void StructureFromSMILES(string smiles)
>         {
>                 int mol = indigoLoadMoleculeFromString(smiles);
>                 indigoLayout(mol);
>
>                 indigoRenderToFile(mol, "test.png"); // Load indigo-renderer.dll and register its options. Return -1
>
>                 indigoSetOption("render-output-format", "png"); // Option is set. Return 1                 indigoSetOption("render-comment", "Caffeine"); // Option is set. Return 1                 indigoSetOption("render-comment-position", "top"); // Option is set. Return 1                 indigoSetOptionXY("render-image-size", 200, 250);  // Option is set. Return 1                                  indigoRenderToFile(mol, "test.png"); // Draw correct picture. Return 1
>
>          }
>
> It might be a good practice to check returned values of functions to find which of them works incorrectly.
>
> As for Indigo .NET universal package, I found that there are some problems in dll unloading which can produce segmentation fault on Linux, so it might be hard to use it now. We will try to fix them after Indigo 1.1 release. Anyway, your comments about experience of using this package on Mono are very appreciated.
>
> Best regards,
> Mikhail Kvyatkovskiy, GGA Software.
>
> On Jun 1, 2012, at 11:05 AM, Mikhail Kvyatkovskiy wrote:
>
> Hello Kyle,
>
> I had reproduced this problem. We will try to fix it.
>
> Also I made an experimental port of Indigo .NET API to Mono, it must be possible to use it on Linux and Mac OS X together with Windows. You can try to use it, but it have not been tested well yet, so it might contain some problems. Here is the link to package with universal versions of .NET libraries:  http://ggasoftware.com/accept?file=indigo-1.1-rc3%2Findigo-dotnet-1.1...

Mikhail Rybalkin

unread,
Jun 4, 2012, 5:03:06 AM6/4/12
to indigo-...@googlegroups.com
Hello Kyle,

It is great that you succeeded in running it!

You can get an images buffer with Indigo in a few lines of code. We have such functionality on Indigo API for .NET and you can just use the same functions in the same order. Here is the link to the code: https://github.com/ggasoftware/indigo/blob/9ce062e50bd8e43b42b9eac6fc4f5f9d3c5ab3a8/api/renderer/cs/IndigoRenderer.cs#L34

You need to create a generic Indigo buffer object via indigoWriteBuffer method, and then use indigoRender method passing this buffer id as a second argument. After that you can get a pointer to the data allocated internally via indigoToBuffer method. You do not need to deallocate this data, because Indigo cares about it. At the end you need to release generic buffer object via indigoFree.

And did you have a chance to look at the universal Indigo .NET package that we built for you and that have to work for Mono too? The link is in the previous message. We found that in some cases it gets failure at the program exit, but before that you can render as many images as you want. This issue is added to our plans after releasing stable version of Indigo. It would be great if you can provide us any information whether it works or not, just to check that there are no other issues.

PS: Don't be confused with all our names, because we have 3 Mikhails in our team :) This is the first thread, where everybody of us sent a message.

Best regards,
Mikhail Rybalkin

ad...@sigma54.ca

unread,
Jun 11, 2012, 2:36:45 PM6/11/12
to indigo-...@googlegroups.com
Hi Mikhail and Mikhail and Mikhail! A lot of Mishas in your office!
 
I finally had a chance to try the universal version of the .Net API and it works great on Linux (at least on CentOS 6)! Using the .NET is a lot easier for me especially with sending the image as a byte array so I really appreciate your work on it!
 
Thanks!
Kyle

kyle.c...@gmail.com

unread,
Jun 11, 2012, 10:21:18 PM6/11/12
to indigo-...@googlegroups.com
Hi Mikhail, Mikhail, and Mikhail! Lots of Mishas in your office!
 
I was able to try the .NET API on Linux and it works (at least on CentOS 6)!
 
Thank you all very much for your help!!
Kyle

On Monday, 4 June 2012 05:03:06 UTC-4, Mikhail Rybalkin wrote:
Reply all
Reply to author
Forward
0 new messages