Calling C unmanaged DLL with with output parameters char **result from C#

In C# library I wanted to call c function from YAZ library


YAZ_EXPORT

int yaz_marc_decode_buf(yaz_marc_t mt, const char *buf, int bsize, char **result, int *rsize);

The problem was that I didn’t know how to specify char **result in managed declaration. I didn’t find similar samplers in Zoom.NET implementation.
The article
Call Unmanaged DLLs from C# recommended to use StringBuilder  for LPSTR (char*) but it wasn’t enough.


After some experimentation I found that adding ref will do the trick(which makes sense).
So the c# declaration is the following:


        [DllImport(“yaz.dll”,


SetLastError = true,


CharSet = CharSet.Ansi,


CallingConvention = CallingConvention.Cdecl,


EntryPoint = “yaz_marc_decode_buf”


)]


        public static extern void yaz_marc_decode_buf(IntPtr yaz_marc_t, String marcBuf, int bsize,


           ref StringBuilder result, ref int rsize);


and the sample code :


StringBuilder result=new StringBuilder() ; /* for result buf */

int result_len = 0; /* for size of result */

YazExt.yaz_marc_decode_buf (_yazMarc, marc_buf, -1, ref result, ref result_len);

string sXml = result.ToString();
Advertisements

Invoke Executable as custom action during Install.

I’ve used MS Installer class to provide custom  actions during setup in a few projects(e.g.see Using VS 2005 Web Setup Project with custom actions).
However if you have some complex logic to do as a part of setup, it is possible that some exception will occur.
I don’t like to hide exceptions, and they are shown to the user,causing installation to rollback.
It is not good, becuse sometimes user wants to ignore exception and use installation even if some custom action failed.
I found that moving code from custom action to executable gives more flexibility,as well as allow to use the same program to customize installation later just by running the same exe.
The Visual Studio SetupProject allowes to specify Custom Action as executable,not as Installer Class.
However during Uninstall,Repair etc, Executable Custom Action can be invoke not as programmer initially designed,and it is required to specify conditions for custom actions. Unfortunately, I had a lot of problems trying to set correct conditions(see Custom action condition to run for a new or upgraded product.and Intermittent execution of custom action for installation of product upgrade. )


To avoid these problems with  Executable Custom Action I desided to return back to Installer Class Custom action, but in Install method the only task is to start  executable and executable will do all required customization of installation.
You can see the code of the class here.

Zoom.NET v0.9c minor problems

I’ve downloaded and tried  Zoom.NET v0.9c with .Net 2.0
I decided to list some issues that I’ve noticed.


 


1. C:ProjectsSamplesZ39.50Zoom.NetHelloWorldClass1.cs


should use PrefixQuery, e.g @”@attr 1=4 “”Gong””” , not simple query “isbn=0253333490”


2. It is required to download latest YAZ from http://www.indexdata.com/yaz/


and copy DLLs from YAZBIN to Zoom.Net.YazSharpyaz


to build YazSharp for Windows successfully.


3. In YazSharp for Windows during search I’ve got:
 An unhandled exception of type ‘System.InvalidOperationException’  Additional information: Cross-thread operation not valid: Control ‘btnSearch’ accessed from a thread other than the thread it was created on.


 


I’ve followed suggestion from “How to solve “Cross thread operation not valid and added to beginning of PerformSearch


            if (this.InvokeRequired)


                this.Invoke(new MethodInvoker(PerformSearch));


            else


            {

LogCategory combo-box in Enterprise Library Exception Handling Application Block.

I’ve tried to create  Enterprise Library Exception Handling Policy similar to described in Take Exception To Critical Errors With Custom Application Blocks , but I wanted to use standard Logging Exception Handler.
However the LogCategory combo-box was empty and I wasn’t able even save the configuration file due to error:”the value for LogCategory can not be null”.
It wasn’t obvious for me that I have to create “Category source“ under “Logging Application Block“ first.
It is not documented properly, a
nd I was surprised that Google returns 0 results for combination
LogCategory  “category source”


 

Side effect of debugging ClientID in DataGrid ChildTable.

I am using Metabuilders ExpandingButtons  and started to get “Please check the page configuration“ error. Some investigation showed that my DataGrid control has two IDs, one as expected from ServerID and another with suffix “__Ctl0”.


<TABLE
<TABLE color="#ff0000" <table id=”dnn_ctr374_ResultsContainer_uscExternalSourceListMarden_grResultItems__ctl0” cellspacing=”2″ cellpadding=”2″ border=”0″ id=”dnn_ctr374_ResultsContainer_uscExternalSourceListMarden_grResultItems”>


JavaScript from  ExpandingButtons tries to use wrong ID(with suffix “__Ctl0”) and alerts the error.
After a lot of debugging I found that I’ve used RecursivelyFindControl function based on code from the thread, which navigated through child controls and Debug.Write ClientID . It seems that for internal ChildTable control of DataGrid it creates not null ClientID and on the Render step,both DataGrid.ClientId and  ChildTable.ClientID are generated.
I beleive that it is a bug in  System.Web.UI.WebControls.ChildTable.AddAttributesToRender code.
If both ChildTable.ClientID and parent DataGrid.ClientId are not empty,only ParentID should be rendered.


ASP.NET CheckBox inside Datagrid returns Checked=false in Postback, if the column is not visible.

In one of ASP.NET pages I’ve used CheckBox column inside Datagrid, and  on some condition the column containing checkbox was invisible 
TemplateColumn.Visible=false
On postback my code tried to read if  control is checked, and it always returned  chk.Checked=false.

It seems that it is done by design and  invisible CheckBox does not have ViewState[“Checked”].

As it suggested in the link Invisible column won’t be rendered to the client.(http://www.velocityreviews.com/forums/t93577)-aspnet-datagrid-template-column-when-inivisible.html):

Make the column invisible with css rule display:none.

Unable to call parameterized constructor for type arguments in Generic class.

I’ve tried to define a generic class, that uses a type argument  derive from the specified base class without parameterless constructor.
The sample code is the following:

    public class KeywordsSearchTestGeneric<T> where T : Keywords//’,new()


    {


        // Methods


        public void ExactMatchCases()


        {


            T keywords1 = new T(“string”);


        }


    }


    public class Keywords


    {


        // Methods


        public Keywords()


        {


            throw new  NotSupportedException();


        }


        public Keywords(string connString)


        {


            Debug.WriteLine(“Keywords “ + connString);


        }


    }


    public class DerivedKeywords : Keywords


    {


        // Methods


        public DerivedKeywords(string connString):base(connString)


        {


            Debug.WriteLine(“DerivedKeywords “ + connString);


 


        }


    }


 However it causes Compiler Error CS0304 “Cannot create an instance of the variable type ‘type’ because it does not have the new() constraint“.
I beleive that the error is irrelevant, because new Constraint (C#) specifies that any type argument in a generic class declaration must have a public parameterless constructor, but my class has a constructor with parameters.
However I’ve added new Constraint to the generic class declaration

    public class KeywordsSearchTestGeneric<T> where T : Keywords,new()

but it gives me another Compiler Error CS0417.
The description of the error includes suggestion :
If you need to call another constructor, consider using a class type constraint or interface constraint. “.
Unfortunately, i’ve started with class type constraint , but didn’t find a solution.