1. Ong Chin Keat
  2. PowerBuilder
  3. Wednesday, 2 August 2023 01:12 AM UTC
*Phenomenon:
Recently we upgraded our PB application OS from Windows7 to Windows11, but found the existing External Remote Function call no longer able to work. Fyi, this Global External Function Call library (AdsAPI32.DLL) actually from an Advantech Digital IO Card from with model PCI-1761. According to vendor, it no longer provides COM based library (AdsAPI32.DLL), instead with another type of Library call DAQNavi. Been contacted the Advantech vendor but they only have programming sample with C#, VB.NET, C++, Java, Matlab. 

*Reproduce Steps:
Over here, would appreciate Appeon support can guide us how should PB scrapping based on below few samples provided by Advantech programming:  

///////////C#///////////
using Automation.BDaq;
...
InstantDiCtrl instantDoCtrl = new InstantDiCtrl();
instantDiCtrl.SelectedDevice = new DeviceInformation(deviceDescription);

// Read profile to configure device
ret = instantDiCtrl.LoadProfile(filePath);
PortDirection[] portDirs = instantDoCtrl.PortDirection;

if (portDirs != null){
    //Set the first two port to output
    DioPortDir dir = DioPortDir.Output;
    portDirs[0].Direction = dir;
  portDirs[1].Direction = dir;
 
  //get port direction and print the direction information
  DioPortDir currentDir = portDirs[0].Direction;
  Console.WriteLine("Current Direction of Port[{0}] = {1}", 0, currentDir.toString());
  currentDir = portDirs[1].Direction;
  Console.WriteLine("Current Direction of Port[{0}] = {1}", 1, currentDir.toString());
} else {
        Console.WriteLine("There is no DIO port of the selected device can set direction!");
}
...
// Write port values to DO port
ret = instantDoCtrl1.Write(portNum, (byte)state);
...
// Read back the DO port status
// Note: for relay output, the read back must deferred until the relay becomes stable
ret = instantDoCtrl1.Read(portNum, out portData);

...


///////////VB.NET///////////
Imports Automation.BDaq

...

Dim portDirs() As PortDirection

If InstantDoCtrl1.PortDirection IsNot Nothing Then
    portDirs = InstantDoCtrl1.PortDirection
   
    'Set the first two port to output.
    Dim dir As DioPortDir
  dir = DioPortDir.Output
  portDirs(0).Direction = dir
  portDirs(1).Direction = dir
 
  'get port direction and print the direction information
  Dim prompt As String
  Dim currentDir As DioPortDir
  currentDir = portDirs(0).Direction
  prompt = "Current Direction of Port[" & Str(0) & "] = " & currentDir.ToString()
  MessageBox.Show(prompt)
  currentDir = portDirs(0).Direction
  prompt = "Current Direction of Port[" & Str(1) & "] = " & currentDir.ToString()
  MessageBox.Show(prompt)
Else
    MessageBox.Show("There is no DIO port of the selected device can set direction!")
End If

'Write port values to DO port
ret = InstantDoCtrl1.Write(portNum, CByte(state))

...

'Read back the DO port status
'Note: for relay output, the read back must deferred until the relay becomes stable
ret = instantDoCtrl1.Read(portNum, out portData);

...


///////////JAVA//////////
import Automation.BDaq.*;

...

DeviceInformation devInfo = new DeviceInformation(deviceDescription);
InstantDoCtrl instantDoCtrl = new InstantDoCtrl();

//Set the selected device.
instantDoCtrl.setSelectedDevice(devInfo);

// Read profile to configure device
ret = instantDoCtrl.LoadProfile(fileDefaultPath);

PortDirection[] portDirs = instantDoCtrl.getPortDirection();
       
if (portDirs != null) {
           
    //Set the first two port to output
    DioPortDir dir = DioPortDir.Output;
    portDirs[0].setDirection(dir);
    portDirs[1].setDirection(dir);
           
    //get port direction and print the direction information
    DioPortDir currentDir = portDirs[0].getDirection();
    System.out.println("Current Direction of Port[" + 0 + "] = " + currentDir.toString());
    currentDir = portDirs[1].getDirection();
  System.out.println("Current Direction of Port[" + 1 + "] = " + currentDir.toString());    
} else {
        System.out.println("There is no DIO port of the selected device can set direction!\n");
}

...

// Write port values to DO port
ret = instantDoCtrl.Write(portNum, (byte)state);

...

// Read back the DO port status
// Note: for relay output, the read back must deferred until the relay becomes stable
ret = instantDoCtrl.Write(portNum, portData);

...

///////////C++///////////
#include "BDaqCtrl.h"
using namespace Automation::BDaq;

...

ErrorCode ret = Success;
InstantDoCtrl * instantDoCtrl = AdxInstantDoCtrlCreate();
DeviceInformation devInfo(deviceDescription);
ret = instantDoCtrl -> setSelectedDevice(devInfo);

// Read profile to configure device
ret = instantDoCtrl->LoadProfile(filePath);

ICollection<PortDirection>* portDirection = instantDoCtrl -> getPortDirection();
if (portDirection != NULL)
{
//Set the first two port to output
DioPortDir dir = Output ;
portDirection -> getItem(0).setDirection(dir);
portDirection -> getItem(1).setDirection(dir);

//get port direction and print the direction information
DioPortDir currentDir = portDirection -> getItem(0).getDirection();
printf(" Current Direction of Port[%ld]=%ld \n",0, currentDir);
currentDir = portDirection -> getItem(1).getDirection();
printf(" Current Direction of Port[%ld]=%ld \n",1, currentDir);
}
else
{
     printf("There is no DIO port of the selected device can set direction!\n");
}



// Write port values to DO port
ret = instantDoCtrl -> Write(portNum, (byte)state);

...

// Read back the DO port status
// Note: for relay output, the read back must deferred until the relay becomes stable
ret = instantDoCtrl -> Read(portNum, &portData);

...


Remarks:

I tried with External Function Call but failed: 
FUNCTION INTEGER BioDoWritePorts(ULONG DeviceNum, LONG port, LONG wvalue) LIBRARY "Bio1761.dll"
FUNCTION INTEGER BioDiReadPorts(ULONG DeviceNum, LONG port, ref LONG wvalue) LIBRARY "Bio1761.dll"

FUNCTION LONG InstantDOCtrl_getDevice() LIBRARY "C:\Windows\SysWOW64\biodaq.dll"
FUNCTION LONG InstantDOCtrl_WriteBit(LONG port, LONG wvalue) LIBRARY "C:\Windows\SysWOW64\biodaq.dll"
FUNCTION LONG InstantDOCtrl_WriteAny(LONG port, LONG wvalue) LIBRARY "C:\Windows\SysWOW64\biodaq.dll"


I tried with ConnectToNewObject but also failed: 
INTEGER li_rtn

oleobject lole_iocard
lole_iocard = create oleobject
li_rtn = lole_iocard.ConnectToNewObject("Automation.BDaq")
       //ConnectToNewObject("Automation.BDaq")

IF li_rtn <> 0 then
      MessageBox( "Error", 'Error running Automation.BDaq4 api.   :' + STRING(li_rtn))
      destroy lole_iocard
      Return -1
ELSE
      MessageBox("OK","OK");
END IF


Appreciate your help in this matter.
NOTE : attached is latest Advantech Driver.
Attachments (1)
References
  1. https://us2.advantech.com/DAQNavi/aboutDAQNavi.aspx
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Wednesday, 9 August 2023 08:18 AM UTC
  2. PowerBuilder
  3. # 1

Hi Ong,

Check your email and Google drive.

I've dropped an example as a test to see if we can get this working in 12.5.

regards

Comment
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 2 August 2023 13:55 PM UTC
  2. PowerBuilder
  3. # 2

Tell the vendor that PowerBuilder interfaces to external DLL's using the __stdcall (also known as WINAPI) interface, just like an application written in C would call a Windows API function. As far as I know, PB cannot communicate via C++ object interfaces. Ask them if their dll is a .NET dll. If so, PB will not be able to call it directly, and you'll likely have to pursue Miguel's suggestion. My guess is that is probably your best bet.

On the positive side, it looks like at first glance that only simple numeric datatype argument values are being exchanged, so at least you may not have to be concerned with ANSI/Unicode differences.

In regards to the PB code you've tried, you said the external function declarations "failed". What does that mean? Did you get a runtime error? No results? Blue Screen of Death? Also, the value for the "LIBRARY" clause should never include any drive/path... just the dll's name and extension. If the dll resides in the executable's search path, Windows will find and dynamically link to it.

Are you running the PB app as a 32-bit app or as a 64-bit app?

Comment
  1. Ong Chin Keat
  2. Tuesday, 8 August 2023 02:04 AM UTC
hi John Fauss,



Thanks for advice. Been found out from Advantech support, yes it's a .Net DLL in this case per mail below :

========================================================================

Cindy Tseng (Advantech)

Aug 8, 2023, 09:54 GMT+8



Dear Ong,



Automation.Bdaq.dll is .Net DLL. We also provide C++ .h header as below:

C:\Advantech\DAQNavi\Inc



Thank you.

Best regards,

Cindy Tseng 曾詩絜 | Online Technical Support | Advantech Co., LTD.

Tel: +886-2-7732-3399 ext.7577 | Fax: +886-2-2794-7301www.advantech.com | 11491 台北市內湖區瑞光路 26 巷 20 弄 1 號

Call Center: 0800-777-111 (Taiwan)

===============================================================



Our PB application running on 32 bits.
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Wednesday, 2 August 2023 05:14 AM UTC
  2. PowerBuilder
  3. # 3

Hi,

I don't understand what "how should PB scrapping " would mean?

You give us example code from the vendor, but you don't tell us / show us the code that you have been using and now no longer works. 

regards.

Comment
  1. Miguel Leeuwe
  2. Wednesday, 2 August 2023 08:13 AM UTC
That's helpful. I think your best shot is to create a C# DLL and expose a public static function to do the job. Then in PB, you can use the DLL import tool to generate a non visual object with the C# function.

I don't have time, now but let me know if you need any help.

regards.
  1. Helpful 3
  1. Ong Chin Keat
  2. Thursday, 3 August 2023 01:39 AM UTC
hi Miguel,



Good day, yes we require further help. If you do provide technical assistance and consultancy, please help to provide more info. If you need to analyze the said PC with IO card plug in, we may arrange a remote session(MS Team with remote) to access our PC here. You may PM me with email ock@southsteel.com.



Looking forward your prompt reply. regards, ong.
  1. Helpful
  1. Miguel Leeuwe
  2. Thursday, 3 August 2023 01:49 AM UTC
Hi,

First of all, I don't work for Appeon. I could maybe help you create a C# DLL, but I would have to know which functions you want to call. A remote session might be a bit difficult since I think you might be on the other side of the world? (I'm in the UK). It would probably also have to be during the weekend.

If you can tell me if your PB application is 32 or 64 bit and you can provide me the C# code of what you want to call from powerbuilder, maybe I can help. I don't have an IO card, so I'm not sure in how far things would compile in C# to generate a DLL.

I'll send you an email when I have some time. (tomorrow is hospital visit).

regards
  1. Helpful 1
There are no comments made yet.
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 2 August 2023 05:06 AM UTC
  2. PowerBuilder
  3. # 4

I think your issue goes WAY beyond the scope of what this simple "question & answer" forum is designed to provide. This is NOT a tech support forum and your issue does not appear to be related to a defect in any Appeon product, so it appears you need technical assistance and/or services.

If you require technical expertise to help you with this issue, I suggest you consider contacting an independent consultant or Appeon authorized partner:

    https://www.appeon.com/consultants

Best wishes and good luck!

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.