LabVIEWForum.de - DLL und Array of Cluster

LabVIEWForum.de

Normale Version: DLL und Array of Cluster
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Nach langem probieren, habe ich es nun endlich geschafft einen Array of Cluster einzulesen und einen größeren auszugeben, leider ist der code noch sehr langsam. Vielleicht hat ja jemand eine Idee wie man den Code verbessern könnte und das häßliche Vorcodieren der DLL verhindern kann.
Grüße Hepman

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "extcode.h"
# include <math.h>


/* LabVIEW created typdefs */

typedef struct {
int32 dimSize;
float64 Numeric[1];
} TD3;
typedef TD3 **TD3Hdl;

typedef struct {
double fitness;
TD3Hdl Array;
} TD2;
typedef struct {
long dimSize;
TD2 arg[1];
} TD4;
typedef TD4 **TD4Hdl;



extern "C" void __declspec(dllexport) Roulette_fast(TD4Hdl input, TD4Hdl output);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
double Round(double Zahl, int Stellen)
{
return floor(Zahl * pow( 10, Stellen) + 0.5) * pow(10, -Stellen);
}



void __declspec(dllexport) Roulette_fast(TD4Hdl input, TD4Hdl output)
{
double Sum=0, InvSum=0;
unsigned int offset=0;
//(*output)->dimSize=100;
unsigned int size=(*input)->dimSize;
unsigned int undersize=(*((*input)->arg->Array))->dimSize;

(*((*output)->arg->Array))->dimSize=(*((*input)->arg->Array))->dimSize;

for(unsigned int i = 0; i < size ; i++)
{
Sum+=((*input)->arg[i].fitness);
InvSum+=1/((*input)->arg[i].fitness);
}

for(i = 0; i < size ; i++)
{
unsigned int run=(unsigned int)(Round((((*input)->arg[i].fitness)/Sum)*100,0));
for(unsigned int k=offset;k<(offset+run);k++)
{
(*output)->arg[k].fitness=(*input)->arg[i].fitness;

for(unsigned int m=0;m<undersize;m++)
{
(*(*output)->arg[k].Array)->Numeric[m]=(*(*input)->arg[i].Array)->Numeric[m];
}
}
offset=offset+run;
}
}
[quote=hepman]Nach langem probieren, habe ich es nun endlich geschafft einen Array of Cluster einzulesen und einen größeren auszugeben, leider ist der code noch sehr langsam. Vielleicht hat ja jemand eine Idee wie man den Code verbessern könnte
Die Frage ist nun, wie vergrößere ich das "Array of Cluster" in C++, so dass es wieder von LabVIEW gelesen werden kann. Ein kleines Beispiel wäre schön. Wenn ich Dimsize einfach erhöhe kommt es zu einem Memory-Absturz. Wie kann ich dem "Array of Cluster" einen größerern Speicher in C++ zuweisen.
Viel Grüße

Hepman
Hmm ja, ein Beispiel ist gut - nur etwas passendes, was man einfach so jemanden in die Hand drücken kann, das habe ich auch nicht. Und dein Cluster mit dem Array als Clusterelement ist auch nicht gerade so das, was sich als Beispiel gut eignen würde.

Erst einmal gibt es im LabVIEW im Menü unter "Help, Search the LabVIEW Bookshelf..." irgendwo eine PDF Datei "Using External Code in LabVIEW". Dort findest du in Kapitel 4 eine Beschreibung, wie die größe von Arrays verändert werden kann.

Vom Ansatz her geht es etwa folgendermaßen, wenn du ein neues Element zum Array hinzufügen willst:
1. du erstellst erst einmal ein neues Element (der Cluster) mit DSNewHandle()
2. Du erstellst ein neues Handle für das Array "Chromosom" am besten gleich in der passenden Arraygröße
3. Jetzt kannst du den Wert für "fitness" eintragen und auch die korrekten Werte im "Chromosom" Array eintragen.
4. mit NumericArrayResize passt du dein "population" Array auf die neue gewünschte Größe an.
5. Nun kannst du den in den Schritten 1 bis 3 erstellten Handle des Clusters in das Array eintragen.

Nunja, ich gebe zu: Bei deinem Array ist das ist schon ein besonderes Vergnügen. Du darfst nur nicht aufgeben.

Ich nehme jetzt doch einmal ein Beispiel und reduziere das aber auf das Wesentliche. Die Behandlung der Fehlersituationen würde sonst den Blick auf das Wesentliche verdecken. Der ursprüngliche Code ist Teil der OpenG Serial Port API - die gibt es noch nicht. Die kompletten Sourcen gibt es derzeit nur bei mir auf direkte Anfrage. Die fertige Serial Port API (aber nicht die OpenG Version) bei mir auf der Webseite (http://www.mhst.de/downloads.html).
Sinn und Zweck der Funktion ist es die Namen aller seriellen Schnittstellen des PC in einem Array zu liefern. Weil ich keine Lust hatte an der Stelle die größe des Strings (eines Portnamens) selbst anzupassen, habe ich das der Funktion LStrPrintf() überlassen - die macht das ganz alleine. Das ist nicht gerade schnell, aber an der Stelle ausreichend. In pszPort ist bereits der Name des Ports als C-String (Null-terminiert) enthalten. Dir wird auch auffallen, dass der Funktion nicht der Pointer auf das Array-Handle übergeben wird, sondern nur das Array-Handle selbst. Das macht die Sache etwas leichter (das solltest du auch so machen). Hier nun der stark vereinfachte Ausschnitt um den String an das Array zu hängen:

[code]//create new handle for the next port name

if ( (shPort = (LStrHandle)DSNewHandle(sizeof(LStr))) == NULL)

{
Referenz-URLs