เหตุใดวิธี IHTMLImgElement put_src จึงส่งคืน E_OUTOFMEMORY เมื่อถูกเรียกจากเธรด

ฉันมี BHO (ส่วนขยาย Internet Explorer) และฉันกำลังพยายามตั้งค่า "data:image/png;base64, [code]" (บัฟเฟอร์รูปภาพที่เข้ารหัส base64) เป็น src ของ IHTMLImgElement เมื่อ put_src ถูกเรียกจากเธรดหลักของ BHO ก็ไม่มีปัญหา แต่ตอนนี้ฉันเรียกจากเธรดอื่น มันจะส่งคืน E_OUTOFMEMORY สตริงที่เข้ารหัส base64 ยาวมาก สำหรับสตริง base64 ที่สั้นกว่า จะส่งคืนโดยไม่มีข้อผิดพลาด

ฉันต้องระบุว่าไม่มีหน่วยความจำรั่ว ฉันใช้เฉพาะพอยน์เตอร์ COM แบบอัจฉริยะ และลบหน่วยความจำที่จัดสรรไว้ทั้งหมด

นอกจากนี้ฉันยังใช้สตริง base64 ประเภทเดียวกันเพื่อเรียก set_พื้นหลังImage สำหรับวัตถุ IHTMLStyle และไม่ส่งคืนข้อผิดพลาด


person evilwhaleboy    schedule 03.03.2014    source แหล่งที่มา
comment
วัตถุเอกสาร MSHTML และ DOM API ไม่ ปลอดภัยต่อเธรด จะต้องถูกเรียกใช้บนเธรดเดียวกันและแห่งเดียวที่สร้างขึ้น ซึ่งเป็นเธรดเดียวกับที่คุณสร้าง BHO   -  person noseratio    schedule 03.03.2014
comment
ขอบคุณสำหรับคำตอบ. อะไรโดยเฉพาะหมายความว่าอะไรไม่ปลอดภัยสำหรับเธรด? ตามที่ฉันเขียนไว้ในโพสต์หลักการเรียก set_พื้นหลังImage กลับมาโดยไม่มีปัญหา   -  person evilwhaleboy    schedule 03.03.2014
comment
ฉันใช้ GIT (ตารางอินเทอร์เฟซสากล) เพื่อรวบรวมและยกเลิกการจัดเรียงวัตถุ IWebBrowser2 ดังนั้นจากสิ่งที่ฉันเข้าใจน่าจะทำงานได้ดี   -  person evilwhaleboy    schedule 03.03.2014


คำตอบ (2)


คำว่า "ไม่ปลอดภัยสำหรับเธรด" หมายความว่าอย่างไรโดยเฉพาะ ตามที่ฉันเขียนไว้ในโพสต์หลักการเรียก set_พื้นหลังImage กลับมาโดยไม่มีปัญหา

ในบริบทนี้ หมายความว่าคุณไม่สามารถเรียกมันว่า โดยตรง จากเธรดอื่นนอกจากเธรดหลัก ซึ่งเป็นที่ที่ BHO ของคุณถูกสร้างขึ้น หากคุณต้องการใช้จากเธรดอื่น ให้รวมอินเทอร์เฟซ IHTMLImgElement ของอ็อบเจ็กต์เข้ากับเธรดนั้น เช่น ด้วย CoMarshalInterThreadInterfaceInStream

ข้อมูลเพิ่มเติม:

person noseratio    schedule 03.03.2014
comment
ฉันใช้ GIT (ตารางอินเทอร์เฟซสากล) เพื่อรวบรวมและยกเลิกการจัดเรียงวัตถุ IWebBrowser2 - person evilwhaleboy; 03.03.2014
comment
@evilwhaleboy แสดงรหัสที่คุณใช้เพื่อรวบรวมวัตถุ WebBrowser/MSHTML COM ผ่าน GIT - person noseratio; 04.03.2014
comment
@evilwhaleboy มันดูโอเคเลย โดยบังเอิญ คุณแคชพอยน์เตอร์ COM ข้ามเธรด เช่น พอยน์เตอร์ไปที่ IHTMLDocument2 หรือไม่ - person noseratio; 04.03.2014
comment
ขออภัยสำหรับคำถามที่อาจเป็นโง่ แต่การแคชตัวชี้ข้ามเธรดหมายถึงอะไร - person evilwhaleboy; 04.03.2014
comment
หมายความว่าคุณอาจบันทึกตัวชี้ไปยังอินเทอร์เฟซ COM บนเธรดหนึ่ง (ในสมาชิกหรือตัวแปรคงที่) จากนั้นใช้บนเธรดอื่นโดยไม่ต้องจัดเรียง - person noseratio; 04.03.2014
comment
ฉันไม่ได้ทำสิ่งนั้น - person evilwhaleboy; 04.03.2014
comment
ฉันเดาว่าข้อผิดพลาด E_OUTOFMEMORY เกี่ยวข้องกับสตริงที่ยาวมาก ~ 75,000 อักขระ แต่ฉันไม่เข้าใจว่าทำไมมันถึงใช้งานได้เมื่อถูกเรียกจากเธรดหลัก และมันไม่ได้อยู่ในเธรดของผู้ปฏิบัติงาน - person evilwhaleboy; 04.03.2014
comment
@evilwhaleboy คุณอาจต้องการลองรวมการโทรนี้ (และข้อมูล) ไปยังเธรดหลักผ่านอินเทอร์เฟซที่คุณกำหนดเองบน BHO ของคุณ จากนั้นเรียก MSHTML บนเธรดหลักโดยตรง - person noseratio; 04.03.2014
comment
ฉันไม่คิดว่าคุณหมายถึงอะไร ฉันต้องทำงานในเธรด ฉันจะเรียกวิธีการในเธรดหลักได้อย่างไร - person evilwhaleboy; 04.03.2014
comment
@evilwhaleboy ติดตามตัวอย่างจากลิงก์ แรก ในคำตอบของฉัน มันมี TSTMARSH ซึ่งใช้อินเทอร์เฟซ ITest และแสดงวิธีการเรียกจากเธรดอื่น ทำเช่นเดียวกันกับ BHO ของคุณ - person noseratio; 05.03.2014

หากออบเจ็กต์ IWebBrowser2 ถูกจัดเรียงไปยังเธรดอื่น สตริงที่ส่งผ่านไปยังเมธอด put_src จะต้องเป็น BSTR ที่จัดสรรด้วย SysAllocString ไม่ใช่ LPWSTR แบบธรรมดา ฉันได้รับคำตอบจากฟอรัมอื่น

person evilwhaleboy    schedule 06.03.2014