Seite 1 von 2

IMA read at address 0

Verfasst: 11.05.2009 12:40
von D@nte
Warum produziert folgender Code mit dem 'Flag' #UseDLL = 0 einen IMA
[line: 39] IMA (read error at address 0)
jedoch mit #UseDLL = 1 nicht obwohl beide Varianten Prinzipiell das gleiche tun?

test.data

Code: Alles auswählen

Enumeration
  #Window
  #File
  #Library
  #String_0
  #String_1
  #String_2
  #Font
EndEnumeration

LoadFont (#Font, "SimSun", 40)

If ReadFile(#File, "X:\test.data")
  input.s = ReadString(#File, #PB_Unicode)
  CloseFile(#File)
EndIf

#UseDLL = 0                               ; 1 use transformation via c_g18030.dll
                                          ; 0 use transformation via MultiByteToWideChar_ / WideCharToMultiByte_
output.s = Space(Len(input))

If #UseDLL
  pcchLeftOverBytes.s = Space(Len(input)) ; UINT that contains GB18030 bytes at the end of the buffer
                                          ; that cannot be converted. These bytes could be the leading
                                          ; bytes of valid GB18030 bytes in the Next incoming GB18030 bytes.

  OpenLibrary(#Library, "c_g18030.dll")
    CallFunction(#Library, "BytesToUnicode", @input, Len(input)*2, @pcchLeftOverBytes, @output, Len(output)*2)
                                          ; Transforms Unicode (GB2212) to GB18030
    output2.s = Space(Len(output))
    CallFunction(#Library, "UnicodeToBytes", @output, Len(output), @output2, Len(output2) * 2)
                                          ; Transforms GB18030 to Unicode (GB2212)
Else
  CodePage  = 54936                       ; CodePage of GB18030
  dwFlags   = 0                           ; Otherwise, the function fails with ERROR_INVALID_FLAGS 

  MultiByteToWideChar_(CodePage, dwFlags, @input, Len(input)*2, @output, Len(output)*2)
                                          ; Transforms Unicode (GB2212) to GB18030
  output2.s = Space(Len(output))
  WideCharToMultiByte_(CodePage, dwFlags, @output, Len(output)*2, @output2, Len(output2) * 2, 0, 0)
                                          ; Transforms GB18030 to Unicode (GB2212)
EndIf

If OpenWindow(#Window, 100, 200, 750, 200, "GB18030 transformation demo")
  If CreateGadgetList(WindowID(0))
    StringGadget(#String_0, 10,  10, 730, 60, "Unicode (GB2212)")
    StringGadget(#String_1, 10,  70, 730, 60, "Unicode (GB2212) -> GB18030")
    StringGadget(#String_2, 10, 130, 730, 60, "GB18030 -> Unicode (GB2212)")
  EndIf

  SetGadgetFont(#String_0, FontID(#Font))
  SetGadgetFont(#String_1, FontID(#Font))
  SetGadgetFont(#String_2, FontID(#Font))

  SetGadgetText(#String_0, input)
  SetGadgetText(#String_1, output)
  SetGadgetText(#String_2, output2)

  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_CloseWindow
      quit = 1
    EndIf
  Until quit = 1
EndIf
End
Ferner kann ich in die Variante #UseDLL nicht zweimal hintereinander auf rufen sprich:

Code: Alles auswählen

!!! PSEUDOCODE !!!

input = ReadString(#File, #PB_Unicode)
output = Space(Len(input))
CallFunction(#Library, "BytesToUnicode", @input, Len(input)*2, @Space(Len(input)), @output, Len(output)*2)
input = ReadString(#File, #PB_Unicode)
output = Space(Len(input)) <= IMA (read error at address 0)
CallFunction(#Library, "BytesToUnicode", @input, Len(input)*2, @Space(Len(input)), @output, Len(output)*2)

Verfasst: 11.05.2009 13:04
von Kaeru Gaman
in line 39 steht bei mir
> output2.s = Space(Len(output))

es wäre hilfreich, wenn du mit der zeilenangabe etwas genauer/ausführlicher wärst.

PS:
wo hast du die codepage her?

Code: Alles auswählen

Debug #CP_ACP
Debug #CP_OEMCP
gibt bei mir keine 54936 aus...

Verfasst: 11.05.2009 13:28
von D@nte
Genauer/Ausführlicher geht's mit der Zeilenangabe nicht, das ist die Zeile die die IDE bemängelt...
Line39: output2.s = Space(Len(output))

Code: Alles auswählen

[XX:XX:XX] Executeable started.
[XX:XX:XX] [ERROR] ****.pb (Line:39)
[XX:XX:XX] [ERROR] Invalid memmory acces. (Read at address 0)
[XX:XX:XX] The Programm was killed.
Mehr / andere Infos hab ich nicht also kA wie ich's genaue sagen soll...

Codepage gibt's im msdn...
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

Konvertierungs page für simplified chinese GB18030

Verfasst: 11.05.2009 14:44
von Kaeru Gaman
mit "ausführlicher" meinte ich, die Zeile mit ner Bemerkung markieren oder noch mal ausschreiben, so wie du's jetzt getan hast.

den code in die IDE kopieren, um zu sehen, welche zeile die 39 ist,
und dann nicht sicher sein, wie viele leerzeilen du evtl. oben drüber gelassen hast,
den aufwand machen sich nur wenige, deswegen schreib besser genau hin, wo der fehler auftritt.
so meinte ich das.


@topic

dass der IMA tatsächlich bei implementierten "einfachen" stringfunktionen auftaucht, ist zumindest ungewöhnlich.

hast du das wirklich als Unicode-Executable compiliert?


weiterhin heißt es in der Help zu MultiByteToWideChar:
int cchMultiByte, // number of characters in string
und bei WideCharToMultiByte:
int cchWideChar, // number of characters in string

also zumindest bei der ersten Längenangabe darfst du nicht *2 schreiben.

ob SizeOfBuffer nun in Byte oder in Char gemeint ist, ist auch noch die Frage,
also, ob du auch bei der zweiten Größenangabe das doppelte angibst.


Ferner:

Code: Alles auswählen

CallFunction(#Library, "BytesToUnicode", @input, Len(input)*2, @Space(Len(input)), @output, Len(output)*2) 
@Space(Len(input)) ist kein korrekter Buffer, du solltest m.A.n. schon einen vorher initialisierten String dort übergeben.

Verfasst: 11.05.2009 15:37
von D@nte
Ich weiß das der Code so wie er ist nicht funktionieren kann WENN man sich an die msdn hält, tatsache ist jedoch das ich nur bei

Code: Alles auswählen

MultiByteToWideChar_(CodePage, dwFlags, @input, Len(input) * 2, @output, Len(output) * 2)
ein korektes Ergebnis bekomme...
"Models\Matters\物品\药品成品掉落\药品成品掉落.ecm"

Code: Alles auswählen

MultiByteToWideChar_(CodePage, dwFlags, @input, Len(input), @output, Len(output))
"Models\Matters\物品\药品? "

Code: Alles auswählen

MultiByteToWideChar_(CodePage, dwFlags, @input, Len(input), @output, Len(output) * 2)
"Models\Matters\物品\药品? "

Code: Alles auswählen

MultiByteToWideChar_(CodePage, dwFlags, @input, Len(input) * 2, @output, Len(output))
"Models\Matters\物品\药品成品掉落\"

>hast du das wirklich als Unicode-Executable compiliert?
Ja es ist eine UnicodeExectutable, sowohl mit SourcefileTextencoding "UTF8" als auch mit "Plain Text" getestet

> @Space(Len(input)) ist kein korrekter Buffer, du solltest m.A.n. schon einen vorher initialisierten String dort übergeben.
>> !!! PSEUDOCODE !!!
Wie dem Bsp-Code zu entnehmen ist wird der als Buffer zu verwendende String vorher intialisiert, der Pseudo-Codeschnipsel sollte auch nur verdeutlich das ich den DLL Part nicht zweimal hintereinander ausführen kann weil dann der gleiche IMA auftritt...

Code: Alles auswählen

pcchLeftOverBytes.s = Space(Len(input))
  OpenLibrary(#Library, "c_g18030.dll")
    CallFunction(#Library, "BytesToUnicode", @input, Len(input)*2, @pcchLeftOverBytes, @output, Len(output)*2) 

Verfasst: 11.05.2009 16:49
von ts-soft
Ohne DLL und xdata kann ich ja nichts testen, aber man sollte grundsätzlich
Prototypes nutzen. Das ermöglicht dann auch Pseudotypes, was die
Konvertierung unnötig macht.

Buffer berechnet man mit StringByteLength()

MultiByteToWideChar_() ist seid PB 4 überflüssig geworden.

Verfasst: 11.05.2009 17:25
von D@nte
>Ohne DLL und xdata kann ich ja nichts testen
:?
Wie wär's wenn du dann die test.data runterläd's wenn du's testen möchtest :D
Die DLL solltest du auch auf dein WIN Rechner haben wird seit WinXP SP1 standardmäßig mitgeliefert, der Code is also prinzipiell schon so gehalten das ihn gut 85% der User im Forum ausführen können sollten, man muss sich halt nur die test.data herunterladen (im Notfall shick ich se euch auch mit der Post :lol:)

>MultiByteToWideChar_() ist seid PB 4 überflüssig geworden.
Pardon?! Inwiefern, hab anscheinend was verpasst...

Verfasst: 11.05.2009 18:12
von ts-soft
D@nte hat geschrieben:>MultiByteToWideChar_() ist seid PB 4 überflüssig geworden.
Pardon?! Inwiefern, hab anscheinend was verpasst...
Okay, ist falsch :oops:
Diese Funktion benötigste tatsächlich für diese komische Codierung.

Die Funktionen der c_g18030.dll kann man nicht direkt aufrufen, sind unter
diesen Name auch garnicht enthalten. Also obige erwähnte API +
WideCharToMultiByte_() nutzen, so steht es auch in der MSDN.

Ansonsten kann ich erstmal nicht helfen, hab keine Zeit mich damit zu
befassen, bin auch noch nie mit dieser Codierung in Kontakt gekommen.
Mußte wohl alleine ausklamüstern.

Verfasst: 11.05.2009 18:34
von D@nte
Hab's ja schon mal Ende des letzten Jahres ausklamüsert (=> http://www.purebasic.fr/german/viewtopic.php?t=18593) mit den Datensätzen die ich zu der Zeit verarbeiten musste, hat's auch wunderbar geklappt nur jetzt fuscht mir da der komische IMA dazwischen...

Und was das nicht verwenden der DLL angeht weiß ich das es in der msdn steht, bei mir funktioniert's aber wunderbar mit der DLL kann die Funktionen auch ansprechen alles wunderbar, vllt sind unterschiedlich Versionen der c_gb18030.dll im Umlauf kA

Musste jetzt grade aber feststellen das das ganze System nicht ganz sauber zu sein scheint bekommen z.B. auch Sachen wie
Surfaces\图标\物品\6级红.ddss
'Erwartungswert' war allerdings
Surfaces\图标\物品\小九阳丹.dds
Sowohl mit DLL als auch über API raus...

Verfasst: 11.05.2009 18:40
von ts-soft
> Und was das nicht verwenden der DLL angeht weiß ich das es in der msdn steht, bei mir funktioniert's aber wunderbar mit der DLL
Zumindest unter Vista enthält die DLL nur eine Funktion die 7 Parameter
erwartet, also keiner der beschriebenen Funktion entspricht