on 01-14-2015 9:56 AM
Hello,
I'm just in the phase of migrating applications from PB 12.5.2 5629 to PB 12.6 4011.
My application uses calls of external functions residing in a C++ DLL with passing structures as arguments.
PB structure:
global type s_s7sbsbulk from structure
boolean bconn
long job
integer machine
integer silo
integer product
long setvalue
long actvalue
integer state
byte manual
end type
C++ struct:
#pragma pack(push, r1, 1)
typedef struct S7SBSBulkData
{
ULONG m_lJobID; // Job-ID
short m_sMachine; // Machine-No. (1 or 2)
short m_sSilo; // Source Silo (1 - 28)
short m_sSiloProduct; // product in silo
ULONG m_lSetValue; // Setvalue in kg
ULONG m_lActValue; // Actual values in kg
short m_sStatus; // Silo-Status
BYTE m_bManual; // manual input
} S7SBSBulkData;
// for GUI (Powerbuilder)
typedef struct S7SBSBLData
{
WORD bConn; // Connection
S7SBSBulkData m_Bulk; // data of loading machine
} S7SBSBLData;
#pragma pack(pop, r1) // stack popped
This worked well for years with PB 12.5.2.
After migrating to PB 12.6 it seems that the alignment of the structure elements in PB has changed.
It seems that each long variable starts now on an address that is a multiple of 4.
PB | C++ | size | PB 12.5.2 address | PB 12.6 address | C++ address |
---|---|---|---|---|---|
bool | WORD | 2 | 0 | 0 | 0 |
long | ULONG | 4 | 2 | 4 | 2 |
int | short | 2 | 6 | 8 | 6 |
int | short | 2 | 8 | 10 | 8 |
int | short | 2 | 10 | 12 | 10 |
long | ULONG | 4 | 12 | 16 | 12 |
long | ULONG | 4 | 16 | 20 | 16 |
int | short | 2 | 20 | 24 | 20 |
byte | BYTE | 1 | 22 | 26 | 22 |
Is this a new feature of PB 12.6 or am I missing something?
Thanks
Werner
PS
This mean that I can't migrate migrate the projects to 12.6 without changing the c++ structures.
So far, there is still no solution to this problem!
(But: only passed 3 months, since I have reported this issue.)
Still hoping for a solution.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Werner and All,
This issue has been addressed in PWRBLDR126000P_4-71000192.ZIP EBF 24672: 12.6 SP00 PL04 (build 4058) that is now available for download.
Please see usage notes below.
When you use a structure or structure array as parameters to external function in the older versions of PowerBuilder, the structure member alignment was one byte. However, the default alignment is 8 bytes on Windows platform, which means that most (if not all) Windows standard APIs use this value to align arguments with structure members. This will cause a mismatch between Windows APIs and PB applications in PB12.5 and earlier versions PowerBuilder. A well adopted solution to this issue was to add some bytes within PowerBuilder structures manually to fill those gaps. Such gap filling can be complex and error-prone if involving complex nested structures. Worse, this solution fails with the introduction of 64bit application development in PB12.6 because the number of bytes you have to fill may be different between 64bit and 32bit applications. This was the major reason to make this change in PB12.6. With PB 12.6 for Windows API and Visual C++ the default structure member alignment is now 8 bytes. The structure member alignment was changed to 8 bytes in PB126 for both x64 and x32 applications. This was an intentional change. Customers can now call Windows API easier and use the same code for both x64 and x32 applications.
Customers can switch to the old behavior in two ways with PB 12.6 build 4058 and above.
1. Check "Use 1-byte structure member alignment in external function" in Tools, System Options, General page (or set UseZp1=1 in [pb] section, pb.ini, the results are same). The effect is global with this setting changed. To make this work at runtime, please remember to deploy your pb.ini file with your application.
2. Add “progma_pack(1)” external function’s declaration, like this.
FUNCTION int STLAREGIO ( ref struc_kfzrechnerneu struc_kfz ) LIBRARY "KFZ_SS.DLL" alias for "STLAREGIO;Ansi" progma_pack(1)
progma_pack(1) is 1-byte align, progma_pack(8) is 8-bytes align. In this way, the effect is only for external function that is declared with this alignment.
Patricia Steinhardt
SAP Active Global Support
This is one of the many reasons people are glad that Appeon is taking over. Whoever decided to make a major change like this and fail to document it should be fired.
The prior version behavior should be the default action. It should be left up to the developer to decide if the function call needs special bit alignment.
Plus, what the heck is a progma anyway? It should be something that makes actual sense to a PowerBuilder developer like this: byte_align(8)
It's not necessary to deploy pb.ini. Either use the switch in System Options or add the progma_pack(1) statement to the function definition.
The idea to switch the behavior at function level is a good idea, so you can mix old and new behavior.
But you're right, the default should be the same as in PB12.5!
It should also be well documented in the help files.
P.S.
In C/C++ the comparable statement is #pragma pack(1). See https://msdn.microsoft.com/en-us/library/2e70t5y1.aspx.
There is probably someone at SAP, who can not read properly.
FUNCTION Long GetTcpServiceInfoSBSSilo(long iNr, ref s_s7sbssilos data) LIBRARY "HBTCPSTU.DLL" progma_pack(1)
Hi Patricia.
I really believe that all that information needs to be referenced somewhere in help files and manuals (which by the way are not available).... Is there any person responsible for powerbuilder documentation, to which we could ask to make the changes to the next bug fix release?
Andreas.
Hi all,
I know this question is "late to the party" But I'm seeking clarification
Please confirm or correct,
Also
What is the behavior if one erroneously adds the progma_pack(1) or uses the INI file method when calling Windows function?
Thanks
I tested this call three ways on a 64 bit EXE deploy
Function FindNextFileW( ( long handle, ref s_finddata findfiledata ) library "kernel32.dll"
Function FindNewtFileW( ... ) library "kernel32.dll" progma_pack(1)
Function FindNewFileW( ... ) library "kernel32.dll" progma_pack(8)
From the application view, all three worked equivalently. There were no errors!
I am concluding that this fix is only for custom DLLs with structure type parameters that cannot be recompile using an 8 bit directive. Everything else is NOT affected
PS: using build 4098
Hi Yakov;
FWIW: I use a lot of SDK calls in my frameworks of which many methods calls pass structures. I have had no issues with PB 12.6 on this using the old PB 12.x external function declarations. I should mention though that all my SDK calls in the frameworks for almost a decade now are solely Unicode based.
HTH
Regards ... Chris
I have the same problem....
Where i can dowload PowerBuilder EBF?
tank's
Angelo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
We just facing same issue. On top we have in our structure string and double values. And from the structure we have an array, which we need to fill. Addresses seems to be changed as well.
e.g.
string
double
string
...
In this constallation we get already problems to access the second string in the structure. The old pointer calculation is now pointing to null .
We need also to know, what was changed in PB12.6, was it by intention and what we have to adjust.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi All,
PB engineering has confirmed that this was an intentional change in PB 12.6 but unfortunately was not included in the documentation.
Below is what I heard back from engineering on CR 777799 that I opened for a different customer experiencing this issue.
When you use a structure or structure array as an external function, in the old version of PowerBuilder, the structure member alignment was one byte. With Windows API and Visual C++ default option(in PB 12.6), the structure member alignment is 8 bytes. You must add some padding member in your structure definition. For x64 applications, the problem becomes more serious as the length of the pointer is 8 bytes. To work around this engineering changed the structure member alignment to 8 bytes for PB126 for both x64 and x32 applications. This is an intentional behavior change. Customers may need to make some changes for some special cases with their external function call, but they can call Window API more easily and use same code for both x64 and x32 applications.
A fix that enables two workarounds to switch to the pre-PB 12.6 behavior has been implemented as a result of CR 777799. I do not know when an EBF with this fix will be available to customers as it was just recently implemented.
Pat Steinhardt
Hi Pat;
That is not a fix its a "kluge" workaround that can not support both. I can see where a PB application is calling older 3rd party DLL's and new ones where the alignment could be a mixed bag.
The proper fox would be to change the structure painter to tag the entire structure or by structure item (element) if a word boundary alignment is required.
Just my $0.02
Regards ... Chris
Kerthunk!! Another nail in the coffin.
It is inconceivable that any responsible manufacturer or any manager at any level could allow such a major change, and a far reaching one for some customers, and then 'forget' to document it.
As Chris says the solution is nothing but a kludge.
Thanks again, SAP.
Incident reported to SAP: 31101 / 2015.
Still waiting for a solution...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Werner;
OUCH .. that would be a major issue with many PB applications! I hope that this is a bug with the 12.6 release ... otherwise a major migration shop stopper IMHO.
BTW: I am assuming that you are using PB Classic?
Regards ... Chris
PS: Reminds me of my old Assembler days when we could ask for variables to be aligned on a word boundary.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
87 | |
10 | |
10 | |
10 | |
7 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.