Autor Beitrag
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Mi 19.04.17 19:41 
Hallo Leute,

ich bin mit meinem Latein am Ende :(
Ich habe eine dynamische Bibliothek in FPC geschrieben und bin grad dabei Header und Beispiele für andere Sprachen zu implementieren. C, C++ und FPC hab ich schon. Jetzt wollte ich noch C# implementieren. Also hab ich ein entsprechendes cs File geschrieben und eine kleine Test-Anwendung gebaut. Bei einem bestimmten Aufruf in die DLL bekomm ich eine AccessViolationException, obwohl es mit der selben Routine in meinen anderen Beispielen ohne Probleme funktioniert. Also hab ich ein paar Debug Ausgaben in meine DLL eingebaut. Die Parameter werden alle richtig übergeben und können auch ohne Probleme gelesen werden. Erst wenn ich ein bestimmtes Objekt innerhalb der DLL erstelle crasht mein Programm. Andere Objekte an der selben Stelle funktionieren. Ein bischen Code:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
function ltsRendererCreate(aHandle: TltsContextHandle; aType: TltsRendererType; aFormat: TtsFormat): TltsRendererHandle; stdcall;
var
  c: TtsContext = nil;
  r: TtsRenderer = nil;
  o: TObject;
begin
  try
    {$IFDEF DEBUG}utlLogger.Log(nil'ltsRendererCreate(Handle=%p; Type=%d; Format=%d)', [aHandle, aType, aFormat]);{$ENDIF}
    result := nil;
    if not CheckContextHandle(aHandle, c) then
      exit;

    if not ValidateFormat(aFormat) then begin
      SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format', [aFormat]));
      exit;
    end;

    // funktioniert
    o := TObject.Create;
    try
      utlLogger.Log(nil'o=%p', [Pointer(o)]);
    finally
      FreeAndNil(o);
    end;

    case aType of
      ltsRendererOpenGL: begin
        {$IFDEF DEBUG}utlLogger.Log(nil'TltsRendererOpenGL.Create(c=%p, Format=%d)', [Pointer(c), Integer(aFormat)]);{$ENDIF}
        r := TltsRendererOpenGL.Create(c, aFormat); // <-- CRASH!!
      end;
      ltsRendererOpenGLES:  r := TltsRendererOpenGLES.Create(c, aFormat);
      end
    else
      SetLastError(ltsErrInvalidEnum, Format('%d is not a valid renderer type', [aType]));
      exit;
    end;

    AddReference(ltsObjTypeRenderer, r);
    result := r;
  except
    on ex: Exception do begin
      SetLastError(ex);
      result := nil;
    end;
  end;
  {$IFDEF DEBUG}utlLogger.Log(nil'ltsRendererCreate=%p', [result]);{$ENDIF}
end;


ausblenden C#-Quelltext
1:
2:
[DllImport("libtextsuite.dll", EntryPoint = "ltsRendererCreate", CallingConvention = CallingConvention.StdCall)]
public static extern RendererHandle RendererCreate(ContextHandle handle, RendererType type, Format format);


Die LogAusgabe vor dem Konstruktor seh ich noch. Aber die Ausgabe in der ersten Zeile vom Konstruktor kommt nicht mehr. Sehr seltsam :?
Kann sich da jmd n Reim drauf machen? Braucht ihr noch mehr Infos? Ich bin für jede Hilfe dankbar :)

MfG Bergmann

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^


Zuletzt bearbeitet von Bergmann89 am Do 20.04.17 09:53, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 20.04.17 04:08 
Ich weiß ja nicht was die Klasse so braucht, aber vielleicht fehlt die COM Initialisierung? Stichwort CoInitializeEx.

Und welche Meldung kommt genau? Adresse 0?
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 20.04.17 08:13 
Guten Morgen,

also die Klasse nutzt keine Interfaces. Dann sollte ich doch auch kein COM brauchen, oder? Hab das CoInitializeEx trotzdem mal rein gebaut. Keine Änderung.
Hier die ganze Exception:
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
System.AccessViolationException ist aufgetreten.
  HResult=0x80004003
  Nachricht = Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist.
  Quelle = <Die Ausnahmequelle kann nicht ausgewertet werden.>
  Stapelüberwachung:
   bei lts.Imports.RendererCreate(UIntPtr handle, RendererType type, Format format)
   bei lts.RendererOpenGl..ctor(Context context, Format format) in G:\Development\libTextSuite\header\examples\cs\libTextSuite.cs: Zeile1729
   bei libTextSuiteExample.MainWindow.OpenGLControl_OpenGLInitialized(Object sender, OpenGLEventArgs args) in G:\Development\libTextSuite\header\examples\cs\MainWindow.xaml.cs: Zeile47
   bei SharpGL.WPF.OpenGLControl.OnApplyTemplate()
   bei System.Windows.FrameworkElement.ApplyTemplate()
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei System.Windows.Controls.Grid.MeasureOverride(Size constraint)
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint)
   bei System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint)
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint)
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei System.Windows.Controls.Border.MeasureOverride(Size constraint)
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei System.Windows.Window.MeasureOverrideHelper(Size constraint)
   bei System.Windows.Window.MeasureOverride(Size availableSize)
   bei System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   bei System.Windows.UIElement.Measure(Size availableSize)
   bei System.Windows.Interop.HwndSource.SetLayoutSize()
   bei System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   bei System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
   bei System.Windows.Window.SetRootVisual()
   bei System.Windows.Window.SetRootVisualAndUpdateSTC()
   bei System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
   bei System.Windows.Window.CreateSourceWindow(Boolean duringShow)
   bei System.Windows.Window.CreateSourceWindowDuringShow()
   bei System.Windows.Window.SafeCreateWindowDuringShow()
   bei System.Windows.Window.ShowHelper(Object booleanBox)
   bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
   bei System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   bei MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   bei System.Windows.Threading.DispatcherOperation.Invoke()
   bei System.Windows.Threading.Dispatcher.ProcessQueue()
   bei System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   bei System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   bei System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   bei System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   bei System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   bei System.Windows.Application.RunDispatcher(Object ignore)
   bei System.Windows.Application.RunInternal(Window window)
   bei System.Windows.Application.Run(Window window)
   bei System.Windows.Application.Run()
   bei libTextSuiteExample.App.Main()

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 20.04.17 11:02 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 20.04.17 11:14 
Hallo,

das Arbeitsspeicher Problem hab ich mittlerweile in den Griff bekommen, aber ich werd es trotzdem heute Nachmittag mal noch auch meinem Laptop probieren.

Den Compiler-Schalter hab ich auch schon entfernt um sicher zu gehen (hab das dann bloß wieder zurück gebaut), das die Ausgabe wirklich kommt. Sie kommt aber nicht. Nebenbei: Der Schalter ist global definiert und der Code um den es geht ist in der selben Unit. Das sollte also auch mit Schalter funktionieren.

Ich hab auch schon versucht GDB an den Prozess zu binden, das ich in die DLL rein steppen kann, aber leider ist es bis jetzt bei dem Versuch geblieben :/

LG

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 20.04.17 11:45 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 20.04.17 12:17 
Format ist in meinem cs File als Enum definiert. Für was wird Format denn in C# genutzt? Mein Intelli Sense und google spucken nichts dazu aus... Ich kenn nur String.Format und das muss ja explizit mit String.XXX aufgerufen werden. Wenn es da Doppeldeutigkeiten geben sollte müsste das der Compiler das eig auch sagen. Die werte kommen ja auch richtig in der DLL an (laut Debug Ausgabe).

Hier mal noch der Link zum Repo, wenn jmd genauer rein gucken will. Anmerkung: Ist alles noch Work in Progress, also nicht wunden wenn noch irgendwo Fehler drin sind...

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 20.04.17 12:24 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 20.04.17 18:37 
Die Basis-Typen hinter dem Enum sind Int32. Also wäre der Prototype wie folgt:
ausblenden C#-Quelltext
1:
2:
[DllImport("libtextsuite.dll", EntryPoint = "ltsRendererCreate", CallingConvention = CallingConvention.StdCall)]
public static extern RendererHandle RendererCreate(ContextHandle handle, Int32 type, Int32 format);
Aber der geht auch nicht :(

€: Ich hab grad mal versucht besagtes Objekt an einer anderen Stelle zu erstellen. Selbes Problem. Es _muss_ an diesem Objekt liegen...
€2: Habs gefunden :suspect: Exception im Konstruktor werfen mag er irgendwie nich. In ner normalen Prozedur geht das, da wird die schön im catch abgefangen und geloggt, aber im Konstruktor knallt's :/
€3: Ok, alles gefixt. Jetzt hab ich nur noch das Problem, dass ich die benötigten OpenGL Funktionen nicht laden kann... Ich bekomm immer nur Null Pointer

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 20.04.17 22:08 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Do 20.04.17 23:16 
Das trägt den neu erstellte Objekt als Renderer in der globalen Handle-Liste ein. Wie oben schon gesagt lag es an einer Exception im Konstruktor. Die wurde geworfen, weil kein gültiger OpenGL Context gebunden war. Ich versteh allerdings noch nicht ganz, warum er dann ne Zugriffsverletzung hat und nicht einfach (wie bei einer normalen Anwendung auch) einfach das Objekt wieder abräumt und die Exception weiter wirf :? So wie ich's jetzt abgeändert hab geht erstmal alles, aber es wäre schön wenn mich zum Thema Exception nochmal jemand erleuchten könnte :D

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 21.04.17 07:06 
Es hat schon Gründe weshalb man in einem Konstruktor niemals mehr machen sollte als reine Initialisierungen einfacher Werte.
Alles andere gehört in Methoden, die nach dem Konstruktor aufgerufen werden. Eben damit man dort eine saubere Fehlerbehandlung machen kann.

Nichtsdestotrotz sollte es funktionieren wie du es dir vorgestellt hast, aber ich vermute, dass dir nicht klar ist, dass eine Exception im Konstruktor zwar weitergereicht wird, vorher aber der Destruktor aufgerufen wird um die Instanz wieder abzuräumen. Ich vermute dort kommt die Exception her, weil du nicht damit rechnest, dass dort etwas nicht initialisiert ist.
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Fr 21.04.17 08:39 
Stimmt, du hast Recht. Daran hab ich gar nich mehr gedacht ^^ Im Destruktor gibts dann einen Funktionszeiger der ins leere zeigt...

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Bergmann89 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Fr 21.04.17 20:10 
Ich brauch mal bitte noch ein wenig Übersetzungshilfe^^ Ich hab noch eine andere Routine, da knallt es jetzt wirklich beim Aufruf der Funktion, weil ich mit den Parametern noch nicht so recht klar komme...
Diesen Delphi/FPC Code:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
TltsHandle              = Pointer;
TltsContextHandle       = TltsHandle;
TltsImageHandle         = TltsHandle;
TltsPostProcessorHandle = TltsHandle;

TtsPosition = packed record
  x, y: Integer;
end;

{$Z4}
TtsColorChannel = (
  tsChannelRed,
  tsChannelGreen,
  tsChannelBlue,
  tsChannelAlpha);
TtsColorChannels = set of TtsColorChannel;

{$Z4}
TtsImageMode = (
  tsModeIgnore,
  tsModeReplace,
  tsModeModulate);
TtsImageModes = array[TtsColorChannel] of TtsImageMode;

function ltsPostProcessorFillPatternCreate(
    aContext: TltsContextHandle;
    aPattern: TltsImageHandle;
    aOwnsPatter: Boolean;
    aPosition: TtsPosition;
    aModes: TtsImageModes;
    aChannels: TtsColorChannels): TltsPostProcessorHandle;  stdcall;

Habe ich in folgenden C# Code umgesetzt:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
using Handle = UIntPtr;
using ContextHandle = UIntPtr;
using ImageHandle = UIntPtr;
using PostProcessorHandle = UIntPtr;

public enum ImageMode : UInt32
{
    Ignore,
    Replace,
    Modulate
};

[Flags]
public enum ColorChannels : UInt32
{
    Empty = 0,
    Red = (1 << 0),
    Green = (1 << 1),
    Blue = (1 << 2),
    Alpha = (1 << 3)
};

[StructLayout(LayoutKind.Sequential, Size = 8, Pack = 1)]
public struct Position
{
    public Int32 x;
    public Int32 y;
};

[StructLayout(LayoutKind.Sequential, Size = 16, Pack = 1)]
public struct ImageModes
{
    public ImageMode R;
    public ImageMode G;
    public ImageMode B;
    public ImageMode A;
};

[DllImport("libtextsuite.dll",
    EntryPoint = "ltsPostProcessorFillPatternCreate",
    CallingConvention = CallingConvention.StdCall)]
public static extern PostProcessorHandle PostProcessorFillPatternCreate(
    ContextHandle handle,
    ImageHandle pattern,
    bool ownsPattern,
    Position position,
    ImageModes modes,
    ColorChannels channels);


Ich bin mir nicht sicher ob das mit den structs so richtig ist...

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 22.04.17 10:35 
- Nachträglich durch die Entwickler-Ecke gelöscht -