เนื่องจากความต้องการของโครงการฉันใช้ Delphi เพื่อเขียน DLL ที่เชื่อมต่อฐานข้อมูลเพื่อส่งออกข้อมูลไปยังไฟล์ SQL ซึ่งใช้ส่วนประกอบ tadoquery
มีวิธีการส่งออกเพียงวิธีเดียวเท่านั้น:
ฟังก์ชั่น DataExport (PATH, INI_Path: PCHAR): จำนวนเต็ม;
หลังจากเขียนฉันเขียน test.exe กับ Delphi สำหรับการทดสอบและพบว่าสามารถใช้งานได้ตามปกติ
จากนั้นเขาก็ส่ง DLL ให้เพื่อนร่วมงานของเขาและขอให้เขาเรียกมันว่าใน PowerBuilder หลังจากรับมันเพื่อนร่วมงานของฉันพบว่าเมื่อมีการเรียก DataExportPB แล้วก็มีรายงานว่าไม่สามารถเปิด DLL เป้าหมายได้ ฉันคิดว่าอาจเป็นเพราะสภาพแวดล้อมที่ทำงานทั้งสองด้านแตกต่างกันดังนั้นฉันจึงคัดลอก test.exe และลอง น่าแปลกที่ test.exe ทำงานได้ดี
เพื่อกำหนดว่าปัญหาเกิดขึ้นจริงฉันใช้ Python และ C# เพื่อทดสอบอีกครั้ง
ไม่เรียก Coinitialize ()
หลังจากตรวจสอบข้อมูลแล้วฉันพบว่าหากใช้ส่วนประกอบ ADO ใน DLL ของ Delphi แล้ววิธีการ coinitialize ของ ActiveX จะต้องเรียกก่อนการใช้งาน หลังจากรู้ปัญหามันจะง่ายขึ้นมาก
ฉันคิดว่า PowerBuilder น่าจะดี แต่ใครจะรู้ว่ามันจะเป็นปัญหาเดียวกัน ตอนนี้ฉันไม่สามารถคิดออกได้ โมดูล ctypes ใน Python ใช้วิธีการโทรใน C และวิธีการผ่านพารามิเตอร์ควรเหมือนกับ powerbuilder แต่ทำไมมันยังเป็นไปไม่ได้ใน PB? เพื่อนร่วมงานของฉันขอให้ฉันเขียนวิธีการส่งออกพิเศษใน DLL เพื่อลองใช้
การทดสอบฟังก์ชั่น: pchar;
เริ่ม
ผลลัพธ์: = 'สตริงทดสอบจากการทดสอบ';
จบ;
วิธีการทดสอบถูกเรียกว่าประสบความสำเร็จใน PB และจากนั้นเพื่อนร่วมงานพยายามโทรหา DataExport อีกครั้งและมันก็ประสบความสำเร็จ! - - - ทำไม วิธีการทดสอบนี้เพียงแค่ส่งสตริงคงที่ ฉันงงงวยจริงๆ
แต่ปัญหาอื่นเกิดขึ้นในเวลานี้
ฉันตรวจสอบรหัส Delphi อย่างระมัดระวังและค้นพบโดยใช้รูปที่ไม่ได้เปิดตัวรหัสของฉันมีดังนี้:
ฟังก์ชั่น DataExport (PATH, INI_Path: PCHAR): จำนวนเต็ม;
วาจา
คำถาม: tadoquery;
เริ่ม
-
Coinitialize ();
แบบสอบถาม: = tadoquery.create (ไม่มี);
-
Query.close;
Query.free;
couninitialize ();
-
จบ;
ไม่มีอะไรผิดปกติ! ในความสิ้นหวังฉันแบ่ง coinitialize () และ couninitialize () เป็นสองวิธีอิสระ
ฟังก์ชั่น init: จำนวนเต็ม;
เริ่ม
พยายาม
Coinitialize ();
ผลลัพธ์: = 1;
ยกเว้น
ในข้อยกเว้น:
ผลลัพธ์: = 0;
จบ;
จบ;
ฟังก์ชั่น uninit: จำนวนเต็ม;
เริ่ม
พยายาม
couninitialize ();
ผลลัพธ์: = 1;
ยกเว้น
ในข้อยกเว้น:
ผลลัพธ์: = 0;
จบ;
จบ;
จากนั้นให้เพื่อนร่วมงานเริ่มต้นในเหตุการณ์การเริ่มต้นแบบฟอร์มจากนั้นปิดเหตุการณ์เพื่อเรียก uninit แก้ไขปัญหา ทุกอย่างเป็นเรื่องปกติ
แม้ว่าปัญหาจะได้รับการแก้ไข แต่ฉันก็ยังไม่เข้าใจว่าทำไมฉันถึงทำเช่นนี้