<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Hello everyone,</p>
<p>I'm trying to make a(nother) C# binding for HarfBuzz, and having some troubles with hb_feature_from_string().</p>
<p>Here's how I called it in C#:</p>
<p>```</p>
<p>// <a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz/PlatformInvoke/Api.Shape.cs#L11">
platform invoke</a><br>
</p>
<p>[DllImport(HarfBuzzDll, CallingConvention = Cdecl)]<br>
public static extern bool hb_feature_from_string(byte[] str, int length, out Feature feature);</p>
<p><br>
</p>
<p>// <a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz/HarfBuzz/Feature.cs">
definition of "Feature"</a></p>
<p>[StructLayout(LayoutKind.Sequential)]<br>
public struct Feature<br>
{<br>
    private uint _tag;<br>
    public uint Value;<br>
    public uint Start;<br>
    public uint End;<br>
}</p>
<p><br>
</p>
<p>// calling hb_feature_to_string (<a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz.Test/ShapeTests/Tests.cs#L44">unit test</a> ->
<a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz/HarfBuzz/Feature.cs#L23">
constructor</a>)<br>
</p>
<p>var bytes = Encoding.ASCII.GetBytes("valt");<br>
if (!Api.hb_feature_from_string(bytes, bytes.Length, out var feature)) throw new ArgumentException();<br>
</p>
<p>```</p>
<p>then <a moz-do-not-send="true" href="https://ci.appveyor.com/project/TJYSunset/hardfuzz/build/0.1.3/tests">
the ArgumentException was thrown</a>, meaning hb_feature_from_string returned false. Also, calling hb_feature_to_string() on the returned `Feature` will result in a random string varying each run, as if read from a wild pointer. However, somehow the `_tag`
 can be successfully DETAGed as "valt".<br>
</p>
<p>From my experience,</p>
<ul>
<li>platform invoke definition is unlikely to blame; the `out` keyword and the usage of `byte[]` for marshaling `char *` proved to work in other API calls.
</li><li>maybe the definition of `struct Feature` is incorrect; I had to define <a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz/HarfBuzz/Buffer/GlyphInfo.cs#L10">
hb_glyph_info_t</a> and <a moz-do-not-send="true" href="https://github.com/TJYSunset/HardFuzz/blob/d3fb178d69e8a88e616c7f3a778978b062b99c6d/HardFuzz/HarfBuzz/Buffer/GlyphPosition.cs#L10">
hb_glyph_position_t</a> as 20-byte-long struct for them to work, even if they only have three or four uint32s. But tried Size=20 with no luck.<br>
</li><li>the passed string is unlikely to be incorrect according to this <a href="https://github.com/ufyTeX/luaharfbuzz/wiki/Feature-Strings">
third-party documentation</a> and my glance at hb-common.cc. </li></ul>
<p>I'm wondering, what part of this process is wrong?</p>
<p>Again, thank you in advance!</p>
<p>Todd<br>
</p>
<pre class="moz-signature" cols="72">-- 
Todd J. York (pseudonym)
zh-Hans-CN, en-US | UTC+08:00
Sent from Thunderbird</pre>
</body>
</html>