Page 1 of 2
First project with PUDS, initialize question
Posted: Fri 22. Mar 2019, 13:33
by ValeV
Hey all,
I am starting to learn how to use PCAN-UDS API.
Unfortunately, I get starter errors, "undefined reference to 'UDS_Initialize@20' and "undefined reference to 'UDS_Uninitialize@4'.
My code:
Code: Select all
#include <iostream>
#include <windows.h>
#include "PCANBasic.h"
#include "PCAN-ISO-TP.h"
#include "PCAN-UDS.h"
using namespace std;
int main()
{
TPUDSCANHandle Channel;
TPUDSStatus Status;
// Set the PCAN-Channel to use (PCAN-USB Channel 1)
Channel = PUDS_USBBUS1;
// Initializing of the UDS Communication session
Status = UDS_Initialize(Channel, PUDS_BAUD_250K, 0, 0, 0);
printf("Initialize UDS: %i\n", (int)Status);
UDS_Uninitialize(Channel);
}
My project folder:
EDIT: Peak dongle is connected to PC, but not to controller (server).
Re: First project with PUDS, initialize question
Posted: Fri 22. Mar 2019, 13:42
by K.Wagner
Hello,
in order to use the PCAN-UDS.dll API, you need to link it statically or dynamically to your project. To link it dynamic you need to use the Windows API functions
LoadLibrary,
FreeLibrary, and
GetProcessAddress. If you want to link it statically, then you need to include the corresponding *.lib file to your project. These lib files are located in the same folder where the dlls are placed within the UDS package you have downloaded.
Re: First project with PUDS, initialize question
Posted: Fri 22. Mar 2019, 14:47
by ValeV
Thank you, it works now.
1 other question. In user guide for PCAN-UDS API I see there is class UDSApi, for which function must be called directly.
So I cannot use
But only like:
May I ask what is the point of such class? What are the advantages of using UDSApi.Initialize(), and not UDS_Initialize() ?
Also, if I want to do this:
Do I have to write custom class from myself? Like
Code: Select all
define mClass.Init( UDS_Initialize(...););
Re: First project with PUDS, initialize question
Posted: Fri 22. Mar 2019, 15:14
by K.Wagner
Hello,
ich you check the help you will see why those classes are there:

- UDS wrapper classes
- API.PNG (20.17 KiB) Viewed 6025 times
As you can see, there are wrappers to use the APIs from other programming environments like .NET (C#, VB.NET; C++/CLR), and Delphi. Principally is the same, but since you cannot use *.lib files for .NET or delphi, one need to load the API dynamically in order to be able to use it.
ValeV wrote:So I cannot use
CODE: SELECT ALL
UDSApi mclass;
But only like:
CODE: SELECT ALL
UDSApi.Initialize(...)
May I ask what is the point of such class? What are the advantages of using UDSApi.Initialize(), and not UDS_Initialize() ?
If you see the declaration of that class you will see why:
In .NET, static classes cannot be instantiated. This class only mimport the functions of the API in .NET, so that you can use them.
ValeV wrote:Also, if I want to do this:
CODE: SELECT ALL
UDSApi mclass;
Do I have to write custom class from myself? Like
CODE: SELECT ALL
define mClass.Init( UDS_Initialize(...););
If you are using C++ and you want to have a class defined that load the API funcitons and allows you to call them, than yes.
Re: First project with PUDS, initialize question
Posted: Fri 22. Mar 2019, 15:37
by ValeV
Got it, thank you a lot, sir.
Re: First project with PUDS, initialize question
Posted: Wed 27. Mar 2019, 12:49
by ValeV
K.Wagner wrote:Hello,
in order to use the PCAN-UDS.dll API, you need to link it statically or dynamically to your project. To link it dynamic you need to use the Windows API functions
LoadLibrary,
FreeLibrary, and
GetProcessAddress. If you want to link it statically, then you need to include the corresponding *.lib file to your project. These lib files are located in the same folder where the dlls are placed within the UDS package you have downloaded.
I did it with dynamic linking, and it works, but there is one "problem" I don't know why happens.
FreeLibrary() function takes a lot of time,
if there was an error initializing PCAN.
Pseudocode:
Code: Select all
PCANUDS* pcan = new PCANUDS()
pcan->loadAPI() // loads functions from dll, with LoadLibrary() and GetProcessAddress() for all functions
pcan->UDS_Initialize() //returns error (lets say if is dongle not connected to PC)
pcan->unloadAPI() // calls FreeLibrary(). Takes like 5 seconds
pcan->UDS_Uninitialize()
delete pcan
If there was no error (initialize succeded), FreeLibrary() finishes quickly.
Can you help me why this happens or is this more of a question for Microsoft? (how FreeLibrary() works and all that, not connected to peak uds libraries)
Re: First project with PUDS, initialize question
Posted: Wed 27. Mar 2019, 16:51
by K.Wagner
Hello,
When calling UDS_Initialize there are some threads that are created for communicate with the underlayer APIs (ISO-TP and PCAN-Basic). These threads are terminated when receiving some signals from the devices. Since no devices are initialized, then those threads terminates only when a timeout is reached (5 seconds). That is why you are seeing this delay.
Nevertheless, we will investigate if we can avoid waiting this time when no connection is found. Thanks for bringing this to our attention!
Re: First project with PUDS, initialize question
Posted: Thu 28. Mar 2019, 08:16
by ValeV
Thank you, it seems I can't "fix" this as just yet. Nevertheless, thank you for explanation.
Re: First project with PUDS, initialize question
Posted: Thu 28. Mar 2019, 09:19
by K.Wagner
Hello,
you can just ask for channel availability before calling Initialize. The code could looks like:
Code: Select all
TPUDSCANHandle CanChannel = PUDS_USBBUS1;
WORD Baudrate = PUDS_BAUD_250K;
TPUDSStatus result;
unsigned int iBuffer = 0;
// Check the availability of a channel before calling UDS_Initialize
//
result = UDS_GetValue(CanChannel, PUDS_PARAM_CHANNEL_CONDITION, &iBuffer,
sizeof(unsigned int));
if (result != PUDS_ERROR_OK)
MessageBox(NULL, "Failed to get value", "Error", MB_OK);
else
{
// The condition value is a flag
//
if((iBuffer & PUDS_CHANNEL_AVAILABLE) == PUDS_CHANNEL_AVAILABLE)
// Channel is available for connection --> UDS_Initialize can be called
//
MessageBox(NULL, "Channel Available - Safe to call UDS_Initialize", "Channel found!", MB_OK);
else
// Channel not available --> UDS_Initialize will not be called
//
MessageBox(NULL, "Channel not Available - please check your device and try again", "Channel not found", MB_OK);
}
In this way, you will never call UDS_Initialize on an inexistent channel, so the problem will not occur.
Re: First project with PUDS, initialize question
Posted: Thu 28. Mar 2019, 11:59
by ValeV
Oh great, works perfectly. Thank you!