Skip to main content

Hi,

A vendor sent me a DLL to interface with an IOBoard.
It turns out that I've "registered" the DLL in the project's References but I can't use its functions because they all say they don't exist.
I can't even see the features
in the object browser (as I can see the other DLL's).

I've been looking at the original C# project that the vendor sent me and they have a class where they have the functionalities defined. I don't know if this will be the solution.
I've also tried converting the instructions of this class but it gives me an error.
What they have is:

[DllImport("C:\\\\Users\\\\utilizador\\\\Downloads\\\\DLL_AcronymV4\\\\DLL\\\\Acronym.dll")]
public static extern int CloseTerminal(ref object vTemplate);

After conversion give me this:
method-id CloseTerminal (reference vTemplate as object) returning return-value as binary-long
attribute DllImport("C:\\Users\\utilizador\\Downloads\\DLL_AcronymV4\\DLL\\Acronym.dll") static extern
attribute DllImport("C:\\Users\\utilizador\\Downloads\\DLL_AcronymV4\\DLL\\Acronym.dll").
end method.

Gives compilation error:
Erro COBCH0937 Attribute 'System.Runtime.InteropServices.DllImportAttribute' not allowed in this context IOBoard3_V1 C:\\Users\\utilizador\\source\\repos\\IOBoard3_V1\\Acronym.cbl 14
Thanks again for your help.

Best regards
Alberto Ferraz


Hi,

A vendor sent me a DLL to interface with an IOBoard.
It turns out that I've "registered" the DLL in the project's References but I can't use its functions because they all say they don't exist.
I can't even see the features
in the object browser (as I can see the other DLL's).

I've been looking at the original C# project that the vendor sent me and they have a class where they have the functionalities defined. I don't know if this will be the solution.
I've also tried converting the instructions of this class but it gives me an error.
What they have is:

[DllImport("C:\\\\Users\\\\utilizador\\\\Downloads\\\\DLL_AcronymV4\\\\DLL\\\\Acronym.dll")]
public static extern int CloseTerminal(ref object vTemplate);

After conversion give me this:
method-id CloseTerminal (reference vTemplate as object) returning return-value as binary-long
attribute DllImport("C:\\Users\\utilizador\\Downloads\\DLL_AcronymV4\\DLL\\Acronym.dll") static extern
attribute DllImport("C:\\Users\\utilizador\\Downloads\\DLL_AcronymV4\\DLL\\Acronym.dll").
end method.

Gives compilation error:
Erro COBCH0937 Attribute 'System.Runtime.InteropServices.DllImportAttribute' not allowed in this context IOBoard3_V1 C:\\Users\\utilizador\\source\\repos\\IOBoard3_V1\\Acronym.cbl 14
Thanks again for your help.

Best regards
Alberto Ferraz


I believe that this .dll is not a C# .DLL but is instead a native C/C++ .DLL. In COBOL you should be able to call it's entry points after first loading the .DLL without defining its signature first. Look at the documentation for directive ILPINVOKE here:

The alternative to specifying ILPINVOKE is to add a reference to the .DLL like you have done.


I believe that this .dll is not a C# .DLL but is instead a native C/C++ .DLL. In COBOL you should be able to call it's entry points after first loading the .DLL without defining its signature first. Look at the documentation for directive ILPINVOKE here:

The alternative to specifying ILPINVOKE is to add a reference to the .DLL like you have done.

Thanks for the tip.

I have already done the indicated but it seems that it is not working yet because I still don't have access to the DLL's features.
Gives error on each call to Acronym::ANYTHING.
I would like to send the project (it is small) for further analysis but I think it is no longer possible to send attachments.
In the Window1 program there is a line that is as follows: "declare m_vDUMP as object = table of binary-char unsigned size (10000000)"
Where should I declare this variable (and how) so that it can be used throughout the Window1 program? Is that it gives error of non-existent variable.

Best regards.

Alberto Ferraz


Thanks for the tip.

I have already done the indicated but it seems that it is not working yet because I still don't have access to the DLL's features.
Gives error on each call to Acronym::ANYTHING.
I would like to send the project (it is small) for further analysis but I think it is no longer possible to send attachments.
In the Window1 program there is a line that is as follows: "declare m_vDUMP as object = table of binary-char unsigned size (10000000)"
Where should I declare this variable (and how) so that it can be used throughout the Window1 program? Is that it gives error of non-existent variable.

Best regards.

Alberto Ferraz

If you zip up the project files and upload it to our ftp site I will take a look at it.

The ftp site is:

 https://amerftp.microfocus.com/

Here are the instructions for upload:

user:       sline_upload
passwd: MFupload007
mkdir forChris
cd forChris
bin
put <file>

Please let me know when it is up there.
Thanks.


If you zip up the project files and upload it to our ftp site I will take a look at it.

The ftp site is:

 https://amerftp.microfocus.com/

Here are the instructions for upload:

user:       sline_upload
passwd: MFupload007
mkdir forChris
cd forChris
bin
put <file>

Please let me know when it is up there.
Thanks.

Hi Chris:

I have already uploaded the zip file called IOBoard3_V1. I don't know if I uploaded correctly because I didn't understand the part of: mkdir for Chris cd for Chris bin put <file> I went to FTP, clicked ADD LOCAL FILE, selected the ZIP and uploaded. I wait for the information if everything is correct.

Best regards

Alberto Ferraz


Hi Chris:

I have already uploaded the zip file called IOBoard3_V1. I don't know if I uploaded correctly because I didn't understand the part of: mkdir for Chris cd for Chris bin put <file> I went to FTP, clicked ADD LOCAL FILE, selected the ZIP and uploaded. I wait for the information if everything is correct.

Best regards

Alberto Ferraz

Do you happen to have the documentation for the various functions within the acronym.dll? Docs that show how to call it from C (not C#)  and what the functions expect as parameters would be useful.


Do you happen to have the documentation for the various functions within the acronym.dll? Docs that show how to call it from C (not C#)  and what the functions expect as parameters would be useful.

Hi Chris,

I have the information the supplier sent me but it's in Portuguese.
I'll upload it to FTP just like I uploaded the .zip.
I don't know if what I send will do. If necessary, 
I can translate the document into English.

Best regards

Alberto Ferraz


Hi Chris,

I have the information the supplier sent me but it's in Portuguese.
I'll upload it to FTP just like I uploaded the .zip.
I don't know if what I send will do. If necessary, 
I can translate the document into English.

Best regards

Alberto Ferraz

I now have the document and Word has been able to translate it for me.

I will put together an example of how these C functions can be called from managed COBOL.


I now have the document and Word has been able to translate it for me.

I will put together an example of how these C functions can be called from managed COBOL.

Do you have any additional documentation that shows the methods in the .dll actually being called from c#? It is confusing because it appears to be a native .dll with entry points and not a COM object yet the documented parameters are COM data types.

I cannot actually load the .dll here because it has several dependent .dlls that I do not have.

Thanks.


Do you have any additional documentation that shows the methods in the .dll actually being called from c#? It is confusing because it appears to be a native .dll with entry points and not a COM object yet the documented parameters are COM data types.

I cannot actually load the .dll here because it has several dependent .dlls that I do not have.

Thanks.

I uploaded to FTP the entire C# demo project that the vendor sent me (DLL_AcronymV4).

I think that there should be what is missing to understand the process, because in the DLL folder there are several DLL's that I don't know if they are linked to that one.
I look forward to the feedback.

Best regards
Alberto Ferraz

I uploaded to FTP the entire C# demo project that the vendor sent me (DLL_AcronymV4).

I think that there should be what is missing to understand the process, because in the DLL folder there are several DLL's that I don't know if they are linked to that one.
I look forward to the feedback.

Best regards
Alberto Ferraz

Sorry it took so long but I got sidetracked.
I still couldn't load the .dll because there are some dependencies on other .dlls such as the Intel Jpeg Library which I do not have but I think I can give you what you need to move on.

I converted the first 4 methods in the C# Acronym class to COBOL. It looks like the following:

This would be called like:
set ret-code = type Acronym::NewTerminal(szCaminhoFicheiroLicenca value m_bEscreverLogs)

       class-id Acronym.
        
       method-id NewTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using szCaminhoFicheiroLicenca as string attribute MarshalAs(type UnmanagedType::BStr)
                                by value m_bEscreverLogs as condition-value attribute MarshalAs(type UnmanagedType::I1)
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id CloseTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using by reference vTemplate as object
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id InitializeTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using by reference vTemplate as object
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id RegisterTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using szAddress as string attribute MarshalAs(type UnmanagedType::BStr)
                                newIP as string attribute MarshalAs(type UnmanagedType::BStr)
                                newMask as string attribute MarshalAs(type UnmanagedType::BStr)
                                newGateway as string attribute MarshalAs(type UnmanagedType::BStr)
                                by value nPortoTCP as binary-long
                                by value nPortoUDP as binary-long
                                by value using_dhcp as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value using_UDP as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value using_ComunicacaoSimples as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value bEscreverLogs as condition-value attribute MarshalAs(type UnmanagedType::I1)
                          returning ret-code as binary-long.
                                                      .
       end method.
       end class.


Sorry it took so long but I got sidetracked.
I still couldn't load the .dll because there are some dependencies on other .dlls such as the Intel Jpeg Library which I do not have but I think I can give you what you need to move on.

I converted the first 4 methods in the C# Acronym class to COBOL. It looks like the following:

This would be called like:
set ret-code = type Acronym::NewTerminal(szCaminhoFicheiroLicenca value m_bEscreverLogs)

       class-id Acronym.
        
       method-id NewTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using szCaminhoFicheiroLicenca as string attribute MarshalAs(type UnmanagedType::BStr)
                                by value m_bEscreverLogs as condition-value attribute MarshalAs(type UnmanagedType::I1)
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id CloseTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using by reference vTemplate as object
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id InitializeTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using by reference vTemplate as object
                          returning ret-code as binary-long.
                                                      .
       end method.

       method-id RegisterTerminal static attribute DllImportAttribute("C:\\\\Users\\\\Acronym-Hugo\\\\Desktop\\\\DLL_AcronymV2\\\\DLL\\\\Acronym.dll").
       procedure division using szAddress as string attribute MarshalAs(type UnmanagedType::BStr)
                                newIP as string attribute MarshalAs(type UnmanagedType::BStr)
                                newMask as string attribute MarshalAs(type UnmanagedType::BStr)
                                newGateway as string attribute MarshalAs(type UnmanagedType::BStr)
                                by value nPortoTCP as binary-long
                                by value nPortoUDP as binary-long
                                by value using_dhcp as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value using_UDP as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value using_ComunicacaoSimples as condition-value attribute MarshalAs(type UnmanagedType::I1)
                                by value bEscreverLogs as condition-value attribute MarshalAs(type UnmanagedType::I1)
                          returning ret-code as binary-long.
                                                      .
       end method.
       end class.

Hi Chris,

There is no problem with the delay and I thank you once again for your patience and availability to help me in these processes.

I already understood the DLL reading process and already created the steps to use it.
Now I'm having a problem right at the start of the application because it gives me a compilation error in the main process.

The manufacturer's demo program starts with the following instruction:
        public static void run()
        {
            TcpServer server = new TcpServer(9990);
        }
Now, when I try to convert it, I convert it to "declare server as type TcpServer = new TcpServer(9990)" but it gives me an error.

I've already created the TcPServer class as per the demo but I can't get over the problem.

COBCH1714 - "type IoBoard3_V1.TcpServer" has no visible constructor with 1 parameter.
If you want, I can upload my solution to better check what's going on.
Best regards
Alberto Ferraz


Hi Chris,

There is no problem with the delay and I thank you once again for your patience and availability to help me in these processes.

I already understood the DLL reading process and already created the steps to use it.
Now I'm having a problem right at the start of the application because it gives me a compilation error in the main process.

The manufacturer's demo program starts with the following instruction:
        public static void run()
        {
            TcpServer server = new TcpServer(9990);
        }
Now, when I try to convert it, I convert it to "declare server as type TcpServer = new TcpServer(9990)" but it gives me an error.

I've already created the TcPServer class as per the demo but I can't get over the problem.

COBCH1714 - "type IoBoard3_V1.TcpServer" has no visible constructor with 1 parameter.
If you want, I can upload my solution to better check what's going on.
Best regards
Alberto Ferraz

How are you declaring the TcpServer server class? Since you are passing a parameter to the New method you might have to create a method overload signature for the new method in your declaration which passes in a parameter. Either that or just use TcpServer server = new TcpServer and then set the appropriate property to the specified port number with the set statement afterwards.

It would be hard for me to work with your solution since I cannot load the .dll due to missing dependencies. 


How are you declaring the TcpServer server class? Since you are passing a parameter to the New method you might have to create a method overload signature for the new method in your declaration which passes in a parameter. Either that or just use TcpServer server = new TcpServer and then set the appropriate property to the specified port number with the set statement afterwards.

It would be hard for me to work with your solution since I cannot load the .dll due to missing dependencies. 

I created a cobol class to define TcpServer.

I think that with your help I managed to resolve the issue. I did it like this:

declare server as type TcpServer = new TcpServer

invoke server::TcpServer(nPort)


I still don't have the expected result in terms of functionality but the program is already working and is already heading to where it is needed.
Thanks again.