Page 1 sur 1

Création/utilisation d'un fichier bibliothèque (.lib)

Publié : lun. 02/nov./2020 11:43
par falsam
■ Petite code de test (test.pb) à compiler (x64) avec l'option Shared DLL dans les options de compilation.

Code : Tout sélectionner

ProcedureDLL.s Majuscule(Buffer.s)
  ProcedureReturn UCase(Buffer)
EndProcedure  

ProcedureDLL.i Additionne(a.i, b.i)
  ProcedureReturn a + b  
EndProcedure
■ Vous devriez obtenir trois fichiers :
test.dll
test.exp
test.lib

■ Pour utiliser test.lib dans mon code principal, j'importe les procédures de cette manière.

Code : Tout sélectionner

Import "test.lib"
  Majuscule(Buffer.s)
  Additionne.i(a, b)
EndImport
■ Et maintenant mon besoin d'éclaircissement.
Pourquoi suis je obligé d'utiliser la fonctions PeekS() pour connaitre le string retourné par la procédure Majuscule(), alors que je n'ai pas ce souci pour l'utilisation de la fonction Additionne()

Code : Tout sélectionner

Import "test.lib"
  Majuscule(Buffer.s)
  Additionne.i(a, b)
EndImport

Debug PeekS(Majuscule("test"))

Debug Additionne(40,2)

Re: Création/utilisation d'un fichier bibliothèque (.lib)

Publié : lun. 02/nov./2020 12:35
par microdevweb
Bonjour Falsam,

C'est écrit dans la doc, avec une Dll le passage de string ce fait par pointeur ce qui justifie l'usage de PeekS, de plus il faut passer (d'après la doc) par une variable global.

Les librairies du moins je penses ne sont rien de plus qu'un moyen plus simple d'utiliser des Dll.

C'est la même chose avec par exemple scintillia, ou pour récupérer un string on doit passer également par un pointeur. Cela n'est pas du à Pb mais à l'os.

Edit :

Dans un projet j'avais fait un module qui appelait une lib et avec toute les fonction identiques à la lib, pour les string je renvoyais simplement le peeks.

Re: Création/utilisation d'un fichier bibliothèque (.lib)

Publié : lun. 02/nov./2020 12:42
par falsam
J'avais bien compris que l'appel à une fonction d'une bibliothéque retournait un pointeur. Mais je ne comprend pas pourquoi utiliser une fonctionnalité de lecture d'un pointeur dans un cas et pas dans l'autre. La logique aurait été que cela soit valable dans tous les cas :wink:

Re: Création/utilisation d'un fichier bibliothèque (.lib)

Publié : ven. 06/nov./2020 15:33
par G-Rom
microdevweb a écrit : Cela n'est pas du à Pb mais à l'os.
Non, cela est dû à PB, PB utilise un "StringManager" maison. Dans le dossier SDK , Dans le Readme , il y a une partie qui explique cela.

VI. Managing strings
--------------------

Note: Some examples are available in the 'VisualC' subfolder, so be sure to check them, it's often easier
to learn from working examples.

Managing strings in PureBasic 4.0 and above isn't obvious anymore. If a function use strings but doesn't
returns string, there is not problem at all. Now when it returns string, there is different case:

1) The function doesn't has string parameter

It's the easiest one, and you can use the SYS_GetOutputBuffer() funtion:.

char *Output = SYS_GetOutputBuffer(int Length, int PreviousPosition)

With this command you ask PureBasic to returns a string buffer of 'Length' (in characters, which means
than it's the same value in unicode or not) and store the pointer value in 'Output'. 'PreviousPosition' is a
value passed in the string function.

ex: Output = SYS_GetOutputBuffer(100, PreviousPosition);

Once you get this buffer, just write the string result in it and you're done.

Note: 'Length' should be the exact returned string length. It doesn't count the null terminating character


2) If the function has some string parameters

You still have to use the above functions, but before you may need to to call SYS_GetParameterIndex() and SYS_ResolveParameter()
if you need to use the string parameters after having called SYS_GetOutputBuffer(). Why that ? Because if one of your
parameter is a composed string (like a$+b$), it will reside on the internal buffer. When you request some length (let's say
a big length), it can be reallocated, which means than your string pointers won't be correct anymore. SYS_GetParameterIndex() will
get the index in the buffer, if the string is in the buffer (or return 0 else). SYS_ResolveParameter() will rebuild the
string pointer once SYS_GetOutputBuffer() will be called.

A typical C code will look like that:

M_PBFUNCTION void PB_LSet(const TCHAR *String, int Length, int PreviousPosition)
{
[...]

ParameterIndex = SYS_GetParameterIndex(String);

Cursor = SYS_GetOutputBuffer(StringLength, PreviousPosition);

if (ParameterIndex)
String = SYS_ResolveParameter(ParameterIndex);

[...]
}

Now, sometimes you can't know the size of the result string (or it will be too long to compute it. In this can, you
can request a fixed size and adjust it at the end with the SYS_ReduceStringSize(Length) function. 'Length' is the
number of byte to reduce the buffer. If you have requested a buffer of 4096 with SYS_GetOutputBuffer() and your
string do only 4000 bytes, you will have to reduce it from 96 bytes ie: SYS_ReduceStringSize(96).