2010-11-03 33 views
7

Tôi có một thư viện tĩnh. Thư viện này có các chức năng sau đây được xác địnhTiền tố L cho các chuỗi trong C++

int WriteData(LPTSTR s) 

Mẫu để gọi hàm là

LPTSTR s = (LPTSTR) L"Test Data"; 
int n = WriteData(s); 

WriteData trở lại 0 nếu thành công và -1 trên thất bại.

Tôi đang viết một DLL động để xuất chức năng này.

int TestFun(LPTSTR lpData) 
{ 
    return WriteData(lpData); 
} 

Một C++ kết quả ứng dụng thử nghiệm

LPTSTR s = (LPTSTR) L"Test Data"; 
TestFun(s); //OK return 0 

LPTSTR s = (LPTSTR) "Test Data";  
TestFun(s); //Fail return -1 

tôi phải gọi nó là từ một ứng dụng C#. Tôi cho rằng chữ ký nhập-DLL của tôi sẽ là:

 [DllImport("Test.dll")] 
     private static extern int TestFun(String s); 

Câu hỏi của tôi rất đơn giản Làm thế nào tôi có thể gọi nó từ .Net? Như bạn thấy tôi có thể kiểm soát

TestFun(LPTSTR lpData) 

nhưng không kiểm soát

WriteData(LPTSTR s) 

Cảm ơn tất cả mọi người cho ý kiến ​​của họ. Cho đến nay tôi đang mắc kẹt trên đúc. Tôi nghĩ rằng vấn đề của tôi sẽ được giải quyết khi tôi woul có thể lấy đầu vào từ người dùng và viết 2 dòng cho đúc thay cho dòng sau đây.

LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and 
    TestFun(s); //OK return 0 
+5

Sử dụng TCHAR có ý nghĩa 10 năm trước. Không còn nữa, không có hệ điều hành không phải Unicode nào mà bạn phải hỗ trợ. Làm tất cả mọi thứ wchar_t và di chuyển trên. –

+0

Tôi có thể làm điều đó bằng cách nào? – Manjoor

+0

Điều gì 'không hoạt động' khi bạn chuyển lpData vào hàm WriteData? – harper

Trả lời

7

Tiền tố L tạo chuỗi là chuỗi wchar_t. Bạn có thể sử dụng chức năng API của Windows MultiByteToWideChar để chuyển đổi chuỗi ANSI thành chuỗi wchar_t.

+0

Nó không hoạt động trong trường hợp của tôi – Manjoor

+1

Làm thế nào nó không hoạt động? –

+6

@Manjoor: Bạn thực sự nên giải thích TẠI SAO nó không hoạt động. Những người này đang cố gắng giúp bạn miễn phí cho bạn và không có lợi cho họ, và bạn đang gạt bỏ những nỗ lực của họ và khiến họ cảm thấy như họ đang lãng phí thời gian của họ vì bạn quá lười biếng để nói với họ chính xác tại sao giải pháp của họ không 't làm việc cho bạn. –

0

Tôi sẽ quấn dây của bạn trong macro _T(...). Bằng cách đó, nó di động giữa các bản dựng ANSI và UNICODE.

Lưu ý rằng bạn đang sử dụng loại chuỗi di động - LPTSTR - hãy lưu ý T. Nó sẽ thay đổi giữa ANSI và UNICODE dựa trên cài đặt xây dựng.

+0

Lưu ý: macro '_T' là Microsoft cụ thể, không phải là chung C++, như LPTSTR. Không phải là khó thực hiện lại. –

6

"Hàm" cụ thể để thực hiện tiền tố L là macro TEXT() hoặc _T(). (TEXT được định nghĩa bởi Windows SDK, _T là một phần mở rộng của Microsoft C Runtime).

Các chức năng này sẽ tự động thêm tiền tố L khi dự án của bạn được xây dựng với hỗ trợ unicode (mặc định cho các dự án mới trong hầu hết các môi trường MS Dev) - hoặc để lại cho các dự án được cấu hình không unicode (hoặc ansi).

Đừng làm diễn viên này:

LPTSTR s = (LPTSTR) L"ABC"; // Working fine 
    WriteData(s); 

Nếu dự án đã từng được cấu hình cho phi Unicode, sau đó L "ABC" vẫn sẽ là một mảng của rộng ký tự, nhưng LPTSTR sẽ trở thành một con trỏ đến một mảng gồm 8 ký tự.

Đây là cách chỉ định đúng chuỗi cho chuỗi Ansi, Unicode hoặc "Văn bản".(Văn bản có thể là Ansi hoặc Unicode tùy thuộc vào cài đặt dự án) (Tôi đã bỏ L vì nó thừa và thêm C, vì chuỗi ký tự phải là hằng số).

PCSTR p1 = "ABC"; 
PCWSTR p2 = L"ABC"; 
PCTSTR p3 = TEXT("ABC"); 
+0

Cảm ơn bạn đã trả lời nhưng nó không giải quyết được vấn đề của tôi. – Manjoor

+5

Làm thế nào về bạn nói cho anh ta những gì không làm việc thay vì đặt gánh nặng vào anh ta để đoán ??? Anh ấy dành thời gian để trả lời câu hỏi của bạn mà không mất chi phí. Bạn ít nhất có thể cho anh ta thông tin _some_. –

1

Tôi nghĩ bạn đang nhầm lẫn, như chức năng của bạn nên chỉ làm việc tốt:

int TestFun(LPTSTR lpData) 
{ 
    return WriteData(lpData); // Should be happy 
} 

Nhưng khi bạn gọi chức năng của bạn, bạn sẽ phải cẩn thận:

TestFun((LPTSTR) L"ABC"); // Will work fine 
TestFun((LPTSTR) "ABC"); // Will not work 

Điều này là do "ABC" và L "ABC" là hai thứ khác nhau. Nếu bạn nhìn vào chúng trong bộ nhớ:

"ABC" | 65 66 67 00 
L"ABC" | 65 00 66 00 67 00 00 00 

Edited thêm:

Chẳng gì bằng L prefix trong Net

Đây chỉ là sai là. Tôi vừa mở "New Project-> C++ -> CLR Console" trong VisualStudio, và dòng đầu tiên là:

Console::WriteLine(L"Hello World"); 
+0

Như tôi đã đề cập trong câu hỏi của tôi, đây sẽ là dll động. Dll này sẽ được gọi từ một ứng dụng .Net. Không có gì giống như tiền tố L trong .Net – Manjoor

+0

Chức năng xuất dll 'TestFun'. Bạn có thể cho tôi biết làm thế nào tôi có thể gọi nó từ một ứng dụng C#? Đây là dll-import [DllImport ("Test.dll ")] private static extern int TestFun (String s); – Manjoor

+0

Cảm ơn nỗ lực, nhưng tôi gọi nó từ C# để thử nghiệm và nó cần phải được gọi từ easylanguage vì vậy tôi không thể sử dụng L. – Manjoor

1

Hãy thử:

[DllImport("Test.dll")] 
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s); 

Thông tin thêm về marshaling với MarshalAsAttribute trên MSDN.

Các vấn đề liên quan